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