C 如何在使用GNU readline从stdin读取时,将消息输出到另一个线程上的stdout,而不会弄乱输入?
对不起,标题太长了。我正在用C语言开发一个网络程序,它可以在标准输出上显示从网络接收到的消息,并通过GNU readline库在标准输入上接受用户输入。 问题是,当用户通过readline在主线程上键入命令时,一条网络消息到达并输出到stdout,这将产生如下结果: 情景: 输入:1234567890C 如何在使用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是光
网络留言:你好
当用户刚刚键入“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的设计。您可以尝试一些技巧,将光标移动转义附加到消息中,并在一次写入中发送所有内容,但仍可能存在竞争条件,并且很难处理已包装的输入行。