更新:Simple Proof of Concept解释不同的行为。
假设我使用tcgetattrtcsetattr设置VMIN = 0, VTIME = 0并移除ICANON,将终端设置为原始模式。
从stdin调用read()永远不会阻塞。我说得对吗?
我的问题是:我是否应该期待stdin上的select()立即返回?
从手册页:
select()pselect()允许程序监视多个文件描述符,直到一个或多个文件描述符为某些类“准备就绪”
I/O操作(例如,可能的输入)。如果可以执行相应的I/O操作(例如,读取(2)),则认为文件描述符准备就绪。
没有阻塞。
基于此,我的第一个答案是“是”。然而,实际上,它在我测试过的大多数linux系统上都会阻塞,但在某些系统上不会阻塞。这是内核错误吗?是否建议以这种方式使用VMIN = 0select()

最佳答案

问题可能是这样的:VMINVTIME的数组条目有两个用途。参考POSIX termios
vmin和vtime下标的值可能分别与veof和veol下标的值相同。
程序在规范模式下读取attributes值,然后将其更改为非规范,并将VMIN设置为零。但是version shownVTIME没有任何关系(这与问题中的描述不匹配)。
例如,请参见Understanding UNIX termios VMIN and VTIME(同样,对于termios,linuxmanual page),其中指出,如果VMINVTIME都为零,则可以进行完全无阻塞的读取。
termios手册页给出0作为VEOL的初始值,而stty manual页将<undef>等同于_POSIX_VDISABLE(非零)(这与POSIX stty一致)。posix似乎没有为eol指定初始值。
通常VEOL将是<undef>,如stty -a所示。也许在你得到非阻塞读取的机器上,情况并非如此。这不一定是内核错误,但可能是ttys的配置问题。

09-13 00:03