【问题标题】:Difference between select() and fcntl()select() 和 fcntl() 的区别
【发布时间】:2018-04-19 10:50:08
【问题描述】:

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

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

现在我的疑问是:

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

  2. 我用 10 秒的超时时间调用 select 以仅检查单个文件 描述符。并且可以在文件上读取数据 描述符几乎立即。在这种情况下,将选择静止块 10 秒?

【问题讨论】:

  • 大多数时候您需要同时使用both,尤其是在处理套接字时。例如,select 可能会说 socket 已准备好在 Linux 上读取,但缓冲数据包的校验和不正确 - 在 @987654330 上检查@。如果连一个字节都没有读取,read 将阻塞……因此两者同时发生。
  • 啊,好吧。谢谢,@AnttiHaapala
  • 即我的观点是,如果您认为非阻塞套接字通常被忙循环,那么您就错了 - 应该使用 select 而这两个是互补的。

标签: c unix select file-descriptor fcntl


【解决方案1】:
  1. 如果select() 超时,但您去读取一个未准备好的阻塞文件描述符,那么您将阻塞。对select() 的调用根本不会影响文件描述符的行为。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 2015-09-10
    • 1970-01-01
    • 2015-02-22
    相关资源
    最近更新 更多