繁体   English   中英

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

[英]GNU Readline (libreadline): Displaying output message asynchronously

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

通过readline重新显示功能的组合(或其他方式)可以实现?

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

问题演示

    #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);
    }

建立

$ g++ -pthread -lreadline test.cpp
$ ./a.out

观察到的输出 :(输入“ foo \\ nbar \\ n”的速度很慢)

? tick
ftick
otick
otick

? tick
tick
bartick
tick

? tick
^C

所需的输出 :(输入“ foo \\ nbar \\ n”的速度缓慢)

tick
tick
tick
tick
tick
? foo

tick
tick
tick
tick
tick
? bar

tick
? ^C

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

我有:

// 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);

}

static inline void
clear_for_output(FILE *fp){
    fputc('\r',fp);
}

每当要打印的内容时,它都会锁定并调用clear_for_output(),将光标移动到当前行的开头。 如有必要,它可以在此时通过调用rl_set_prompt()来更改提示。 完成后,它将调用ake_input_thread(),释放锁并导致重新显示。

我不确定这是否适用于您输入了多行文本并对此表示怀疑的情况,并且不关心此时此刻是否可能正式发现新的令人沮丧的错误,因此您可以自己尝试一下。

应该使用的功能:

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

似乎可以从任何线程调用这两个函数。 但是,它可能会引入竞争条件(文档中没有说明从多个线程使用readline函数是否安全),因此,最好使用rl_event_hookrl_getc_function (因为rl_event_hook键时不会调用rl_event_hook )来调用该函数主线程。 还请记住,当没有运行的readline功能时,要处理“说”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM