【发布时间】:2018-04-19 10:50:08
【问题描述】:
按照我的理解 - 我们可以使用fctnl 将文件描述符标记为非阻塞,因此每当我们对该文件描述符调用任何阻塞操作时,它都会出错并修改errno 以指示该文件描述符还没有准备好。我们有责任经常轮询文件描述符并在它准备好时读取或写入。
使用select,我们传入三个文件描述符数组(读取、写入和除外),然后select 在给定的时间间隔内轮询文件描述符,修改数组以指示哪些文件描述符可用于指定行动。而select本身就是一个阻塞操作。
现在我的疑问是:
假设我在需要的数组文件描述符上调用
select被读取并且它在没有检测到任何事件的情况下超时。现在如果我打电话read在文件描述符之一上,它会阻塞还是返回 E_WOULDBLOCK / E_AGAIN,即使我没有先使用fcntl?我用 10 秒的超时时间调用 select 以仅检查单个文件 描述符。并且可以在文件上读取数据 描述符几乎立即。在这种情况下,将选择静止块 10 秒?
【问题讨论】:
-
大多数时候您需要同时使用both,尤其是在处理套接字时。例如,
select可能会说 socket 已准备好在 Linux 上读取,但缓冲数据包的校验和不正确 - 仅 在 @987654330 上检查@。如果连一个字节都没有读取,read将阻塞……因此两者同时发生。 -
啊,好吧。谢谢,@AnttiHaapala
-
即我的观点是,如果您认为非阻塞套接字通常被忙循环,那么您就错了 - 应该使用
select而这两个是互补的。
标签: c unix select file-descriptor fcntl