Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在使用GNU readline从stdin读取时,将消息输出到另一个线程上的stdout,而不会弄乱输入?_C_Pthreads_Readline_Libreadline - Fatal编程技术网

C 如何在使用GNU readline从stdin读取时,将消息输出到另一个线程上的stdout,而不会弄乱输入?

C 如何在使用GNU readline从stdin读取时,将消息输出到另一个线程上的stdout,而不会弄乱输入?,c,pthreads,readline,libreadline,C,Pthreads,Readline,Libreadline,对不起,标题太长了。我正在用C语言开发一个网络程序,它可以在标准输出上显示从网络接收到的消息,并通过GNU readline库在标准输入上接受用户输入。 问题是,当用户通过readline在主线程上键入命令时,一条网络消息到达并输出到stdout,这将产生如下结果: 情景: 输入:1234567890 网络留言:你好 当用户刚刚键入“7”时,网络消息到达 终端上的实际输出: 输入>1234567Hello 890_ 有没有办法得到这样的输出 你好 输入>1234567890_ p、 s.uu是光

对不起,标题太长了。我正在用C语言开发一个网络程序,它可以在标准输出上显示从网络接收到的消息,并通过GNU readline库在标准输入上接受用户输入。 问题是,当用户通过readline在主线程上键入命令时,一条网络消息到达并输出到stdout,这将产生如下结果:

情景:

输入:1234567890
网络留言:你好
当用户刚刚键入“7”时,网络消息到达

终端上的实际输出:

输入>1234567Hello
890_

有没有办法得到这样的输出

你好
输入>1234567890_

p、 s.uu是光标


提前谢谢

您应该在这两个线程之间进行某种同步。一个互斥锁或只是一个从一个线程到另一个线程的标志,指示它正在处理stdin或stdout。

这可以使用库来完成。

转储
读取行
并读取用户输入的每个
字符。如果在用户输入时收到任何网络消息,请清除当前行,输出网络消息,然后重新打印用户当前输入的行

这似乎是一项艰巨的工作,但这是我现在唯一想到的办法


如果您确实转储了
readline
,那么您可以使用
curses
,这使它更容易…

好的,我在四处搜索后找到了解决方案,并对printf()进行了以下替换。通过使用rl_replace_line(“,0”),它将清除当前行并将光标放在行的开头,然后我可以打印一行消息,然后恢复readline提示符,将原始行替换回原位,并恢复光标位置。
但是,此黑客需要调用此printf函数以在结尾包含一个\n,否则该行将被readline覆盖

#define printf(...) my_rl_printf(__VA_ARGS__)
void my_rl_printf(char *fmt, ...)
{
    int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0;
    char *saved_line;
    int saved_point;
    if (need_hack)
    {
        saved_point = rl_point;
        saved_line = rl_copy_text(0, rl_end);
        rl_save_prompt();
        rl_replace_line("", 0);
        rl_redisplay();
    }

    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);

    if (need_hack)
    {
        rl_restore_prompt();
        rl_replace_line(saved_line, 0);
        rl_point = saved_point;
        rl_redisplay();
        free(saved_line);
    }
}

在这种情况下,我必须等待用户完成输入以显示传入消息。然而,消息一到达就应该显示出来。哦,那么我猜RedX的方法就是答案。不幸的是,from、curses和readline没有混合。我认为你想要实现的是相当困难的,因为readline的设计。您可以尝试一些技巧,将光标移动转义附加到消息中,并在一次
写入中发送所有内容,但仍可能存在竞争条件,并且很难处理已包装的输入行。