select() 和 fcntl() 之间的区别

Difference between select() and fcntl()

按照我的理解——我们可以使用 fctnl 将文件描述符标记为非阻塞,因此每当我们对该文件描述符调用任何阻塞操作时,它都会出错并修改 errno 表示文件描述符还没有准备好。我们有责任经常轮询文件描述符并在准备就绪时读取或写入。

使用 select,我们传入文件描述符的三个数组(读取、写入和除外),然后 select 在给定的时间间隔内轮询文件描述符,修改数组以指示哪个文件描述符可用于指定的操作。而select本身就是阻塞操作

现在我的疑惑是:

  1. 假设我在需要的数组文件描述符上调用 select 被读取并且它在没有检测到任何事件的情况下超时。现在如果我打电话 read 在其中一个文件描述符上,它会阻塞还是 return E_WOULDBLOCK / E_AGAIN, 即使我没有先使用 fcntl

  2. 我用 10 秒的超时调用 select 以仅检查单个文件 描述符。并且可以在文件上读取数据 描述符几乎立即。在这种情况下,select 是否仍然会阻塞 10 秒?

  1. 如果select()超时但是你去读一个没有准备好的阻塞文件描述符,那么你就会阻塞。对 select() 的调用根本不会影响文件描述符的行为。

  2. 如果数据立即就绪,select() 调用将立即 return。如果数据在 1 秒后准备就绪,则 select() 调用将在 1 秒后 return。如果在此期间没有数据准备好(或者如果数据在超时发生前一小部分到达),它只会在 10 秒后 return。