我无法理解为linux中的select()设置writefds添加描述符意味着什么。我写了一些简单的代码,它将stdout的描述符添加到writefds集并使用NULL超时。现在,我的代码只是无限循环检查是否设置了此描述符,如果设置了,则打印“WRITING”。当我运行我的代码时,它只是将“WRITING”打印到无穷大。当我为stdin执行此操作时,会发生同样的事情。同样,循环中没有其他代码。 stdin / stdout总是准备好写作吗?
答案 0 :(得分:3)
这意味着您可以在该fd上调用write,并且内核承诺不会阻塞并消耗至少1个字节。
更多细节。如果您的套接字未处于非阻塞模式且与套接字关联的内核缓冲区已满,则内核将使您的线程进入休眠状态,直到它可以清空某些缓冲区并且能够消耗部分写入。
如果您的套接字处于非阻塞模式且内核缓冲区已满,则写入将立即返回而不消耗任何字节。
答案 1 :(得分:2)
“stdout随时准备写作”这个问题的答案是“它取决于。”
stdout可以连接到任何可以作为文件描述符打开的东西 - 比如磁盘文件,网络套接字或管道。通常的情况是它连接到终端设备。
这些类型的文件描述符中的大多数都可以阻止写入(这意味着它们在select()
返回后可能不会被标记为可写),但通常只有在您向它们写入非常大量的数据时(所以填补了某种缓冲区)。 “大量”因设备类型而异 - 如果您的stdout终端是9600波特串行设备,那么您可以很容易地填充写缓冲区;一个xterm,而不是那么多。
某些设备将从不阻止 - 例如磁盘文件或/dev/null
。 (write()
到磁盘文件可能不会立即完成,但这不会被视为“阻塞” - 这是“磁盘等待”。
答案 2 :(得分:1)
是的,来自FD_ISSET(fd, &writefds)
的真实回报意味着fd
是可写的。如果在获得select()
或EWOULDBLOCK
(至少在Linux上等效)后,在writefds中使用该FD设置EAGAIN
,则会阻塞,直到FD再次可写为止。
还有更多的东西。例如,如果你对它进行了非阻塞connect()
,你得到EAGAIN
,并且调用select()
等待建立连接,则FD也被认为是可写的。该建立在writefds中发出信号。