首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非阻塞stdio

非阻塞stdio
EN

Stack Overflow用户
提问于 2009-08-14 04:24:25
回答 3查看 3.9K关注 0票数 3

我正在开发一个程序,它将从控制台接收用户输入,并在单独的线程中打印输出。我希望避免这样的情况,即用户在输入内容的过程中,一个printf出现并在光标处打印出来。

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

EN

回答 3

Stack Overflow用户

发布于 2009-08-14 04:37:39

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

代码语言:javascript
复制
#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)之前,您必须恢复终端:

代码语言:javascript
复制
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
    /* handle error */
}
票数 4
EN

Stack Overflow用户

发布于 2009-08-14 04:31:52

下面是一个如何从C语言中关闭echo的例子,直接取自an HP forum (我没有亲自测试过它):

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

#include #include #include #include #define STDIN_FDES 0 struct termios save;int main(int argc,char *argv[]) { int cc = 0;char s_tmp80,*p = NULL;struct termios work;cc = tcgetattr(STDIN_FDES,&save);work =保存;work.c_lflag &= ~(回应);cc = tcsetattr(STDIN_FDES,TCSANOW,&work);(空)printf(“\n nEnter:");(空) fflush(stdout);p= fgets(s_tmp,sizeof(s_tmp),stdin);if (p != NULL) (空) printf("Out -> %s\n",p);cc = tcsetattr(STDIN_FDES,TCSANOW,&save);return(cc);}

注意:使用信号处理程序来捕获SIGINT、SIGTERM、...并使用原始termios重置终端,因为最后的tcsetattr()获胜,并且这适用于终端设备,而不仅仅是进程。如果在关闭echo的情况下关闭进程,那么shell中的进程也会关闭。

否则,如果Bash是一种合适的方法,显然您可以只使用stty -echo

票数 2
EN

Stack Overflow用户

发布于 2009-08-14 05:35:21

如果我正确理解了您的问题,那么关闭echo或使用非阻塞I/O不是解决方案。相反,您希望防止后台线程中断用户输入线程,对吧?

为此,您需要访问原始按键,而不是行缓冲输入。我不知道您为什么对ncurses或类似的库过敏;这就是它们的作用!我猜你可以用termios或ioctl调用来做这件事,如果你是这样做的话……

但是要解决多线程TTY输出问题,您可以这样做:

1)创建互斥锁,控制谁可以访问控制台

后台线程中的,输出一条消息:

抓取互斥锁;编写消息;释放互斥锁;继续睡眠!

用户输入线程中的:

当检测到新的输入时,抓取互斥锁。保持独占访问,直到用户按回车键,然后释放互斥量,给后台线程一个对话的机会。

这有帮助吗?

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

https://stackoverflow.com/questions/1276029

复制
相关文章

相似问题

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