首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >libreadline (libreadline):异步显示输出消息

libreadline (libreadline):异步显示输出消息
EN

Stack Overflow用户
提问于 2012-02-15 20:39:49
回答 2查看 1.7K关注 0票数 1

在使用readline (阻塞)进行用户输入时,我希望从另一个线程异步地将文本行输出到控制台。此外,我希望从控制台中删除读行提示符和当前的部分输入行,写入输出行,然后恢复读行提示符和部分用户行,以便显示输出被写入“上面”提示符。

通过什么方式组合读行重新显示功能(或其他)可以实现这一点?

(重新显示函数文档:http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC35)

问题演示

代码语言:javascript
复制
    #include <readline/readline.h>
    #include <readline/history.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <pthread.h>

    bool run = true;

    void* log_thread(void*)
    {
            while (run)
            {
                    sleep(1);
                    // WHAT TO DO HERE?
                    write(1, "tick\n", 5);
            }
    }

    int main()
    {
            pthread_t t;
            pthread_create(&t, 0, log_thread, 0);

            while (true)
            {
                    char* p = readline("? ");
                    free(p);

                    if (!p)
                            break;
            }

            run = false;
            pthread_join(t,0);
    }

构建

代码语言:javascript
复制
$ g++ -pthread -lreadline test.cpp
$ ./a.out

观察到输出:(输入"foo\nbar\n“输入缓慢)

代码语言:javascript
复制
? tick
ftick
otick
otick

? tick
tick
bartick
tick

? tick
^C

期望的输出:(输入"foo\nbar\n“,输入速度慢)

代码语言:javascript
复制
tick
tick
tick
tick
tick
? foo

tick
tick
tick
tick
tick
? bar

tick
? ^C
EN

回答 2

Stack Overflow用户

发布于 2012-06-11 00:08:23

我是在我的程序的控制台版本中这样做的(https://github.com/dankamongmen/omphalos)。这个特定的代码来自https://github.com/dankamongmen/omphalos/blob/master/src/ui/tty/tty.c

我有:

代码语言:javascript
复制
// Call whenever we generate output, so that the prompt is updated
static inline void
wake_input_thread(void){
    if(input_tid){
            pthread_kill(*input_tid,SIGWINCH);
            rl_redisplay(); // FIXME probably need call from readline contex
    }
    pthread_mutex_unlock(&promptlock);

}

代码语言:javascript
复制
static inline void
clear_for_output(FILE *fp){
    fputc('\r',fp);
}

每当有东西想要打印时,它都会获取锁并调用clear_for_output(),将光标移动到当前行的开头。如果有必要,它可以通过调用rl_set_prompt()在这个时候更改提示符。完成后,它调用wake_input_thread(),释放锁并导致重新显示。

我不确定在你输入超过一行文字的情况下,这个方法是否有效,并且对此表示怀疑,也不想正式发现什么可能是新的、令人沮丧的错误,所以你可以自己尝试一下。

票数 1
EN

Stack Overflow用户

发布于 2019-10-02 16:37:10

应使用的职能:

  • rl_clear_visible_line().打印line.
  • rl_on_new_line(); rl_redisplay();不能很好,因为它只是将光标移动到行的开头,而不删除行内容,而且当有多个输入\r (或rl_forced_update_display();):在打印之后,它无法正常工作。

似乎可以从任何线程调用这两个函数;但是,它可能会引入争用条件(文档中并没有说明使用来自多个线程的读行函数是否安全),因此最好使用rl_event_hookrl_getc_function (因为持有密钥时不调用rl_event_hook )来调用主线程的函数。此外,当没有运行readline函数时,请记住处理says。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9300974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档