非阻塞的stdio

我正在开发一个程序,它将从控制台接受用户input,并在单独的线程中进行打印输出。 我想避免用户在input内容的一半,并且printf出现并在光标处自行打印的情况。

有没有办法在控制台窗口中执行c中的非阻塞io? 理想情况下,捕获按键或类似的东西,使用户input的内容不会出现在屏幕上。 我正在开发Ubuntu,最好是如果我不必使用像ncurses的东西。

使用termios您可以禁用终端回显:

 #include <termios.h> struct termios oflags, nflags; tcgetattr(fileno(stdin), &oflags); nflags = oflags; nflags.c_lflag &= ~ECHO; nflags.c_lflag |= ECHONL; if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) { /* handle error */ } 

那么在退出之前(使用atexit )你必须恢复终端:

 if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) { /* handle error */ } 

下面是一个关于如何关闭C语言的例子,直接从惠普论坛 (我没有亲自测试过):

好的,这应该是一个关闭回声的简单例子:

 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <termios.h> #define STDIN_FDES 0 struct termios save; int main(int argc, char *argv[]) { int cc = 0; char s_tmp[80],*p = NULL; struct termios work; cc = tcgetattr(STDIN_FDES,&save); work = save; work.c_lflag &= ~(ECHO); cc = tcsetattr(STDIN_FDES,TCSANOW,&work); (void) printf("\nEnter value: "); (void) fflush(stdout); p = fgets(s_tmp,sizeof(s_tmp),stdin); if (p != NULL) (void) printf("Out -> %s\n",p); cc = tcsetattr(STDIN_FDES,TCSANOW,&save); return(cc); } 

注意:有信号处理程序来捕获SIGINT,SIGTERM,…并使用原始的termios重置终端是非常重要的,因为最后一个tcsetattr()获胜,这不仅仅适用于终端设备。 如果你离开这个进程,它也会被关闭。

否则,如果Bash是一个合适的方法,显然你可以做stty -echo

关闭回声或使用非阻塞I / O不是答案,如果我正确地理解你的问题。 相反,你想阻止后台线程中断用户输入线程,对吧?

为此,您需要访问原始按键,而不是线路缓冲输入。 我不知道你为什么对ncurses或类似的图书馆过敏; 这就是他们的目的! 我想你可以用termios或ioctl调用,如果这是你如何滚动….

但是为了解决你的多线程TTY输出问题,你可以这样做:

1)创建一个互斥体来控制谁可以访问控制台

在后台线程中输出消息:

抓住互斥体; 写信息; 释放互斥体; 回去睡觉!

在用户输入线程中:

当检测到新的输入时,抓住互斥锁。 保持独占访问,直到用户点击进入,然后释放互斥量,并让后台线程有机会通话。

这有帮助吗?