更新: Simple Proof of Concept,说明不同的行为。
假设我使用tcgetattr
和tcsetattr
设置VMIN = 0, VTIME = 0
并删除ICANON
,将终端设置为原始模式。
从stdin调用read()
永远不会阻止。我是对的吗?
我的问题是:我应该期待stdin上的select()
立即返回吗?
从手册页:
select()
和pselect()
允许程序监视多个文件描述符,等待一个或多个文件描述符为某些类“准备好” I / O操作(例如,输入可能)。如果可以执行相应的I / O操作(例如,read(2)),则认为文件描述符已准备就绪 不阻止。
基于此,我的第一个答案是“是”。但是,在实践中,在我测试过的大多数Linux系统上都会阻塞,但它并没有阻止某些系统。 这是内核错误吗? 是否建议以这种方式使用VMIN = 0
和select()
?
答案 0 :(得分:0)
问题可能是:VMIN
和VTIME
的数组条目有两个目的。参考POSIX termios:
VMIN和VTIME下标可能分别与VEOF和VEOL下标具有相同的值。
程序在规范模式下读取attributes
值,然后将其更改为非规范,并将VMIN
设置为零。但是version shown对VTIME
没有任何作用(与问题中的描述不符)。
例如,请参阅 Understanding UNIX termios VMIN and VTIME (同样,对于termios的Linux manual page),其中注意到VMIN
和VTIME
都是零,那么你可以完全无阻塞读。
termios手册页给出VEOL
的初始值为零,而stty manual页面将<undef>
等同_POSIX_VDISABLE
(非零)(同意{{3} }})。 POSIX似乎没有为eol
指定初始值。
正常VEOL
为<undef>
,如stty -a
所示。也许在你获得非阻塞读取的机器上,情况并非如此。这不一定是内核错误,但可能是TTY的配置问题。