【问题标题】:Will select() block if called while there is still data to be read?如果在仍有数据要读取时调用 select() 会阻塞吗?
【发布时间】:2012-06-14 19:25:12
【问题描述】:

如果一个socket有数据要读取并且调用了select()函数,会select():

  1. 立即返回,表示套接字已准备好读取,或者
  2. 阻塞直到套接字上接收到更多数据

??

【问题讨论】:

    标签: linux sockets select network-programming


    【解决方案1】:

    它可以很容易地进行测试,但我向您保证,如果其中一个 readfds 上已有数据可供读取,则 select() 将永远不会阻塞。如果在这种情况下它确实阻塞了,那么它对于使用非阻塞 I/O 进行编程就不是很有用了。以您在 select() 上循环的示例为例,您会看到要读取的数据,然后您就读取了它。然后,当您处理读取的数据时,会进入更多数据。当您返回 select() 时,它会阻塞,等待更多数据。但是,连接另一端的对等方正在等待对已发送数据的响应。您的程序最终会永远阻塞。您可以通过超时等来解决它,但重点是提高非阻塞 I/O 的效率。

    如果 fd 在 EOF,即使多次调用,select() 也永远不会阻塞。

    【讨论】:

      【解决方案2】:

      man 2 select 似乎很直接地回答了这个问题:

      select() 和 pselect() 允许程序监视多个文件描述符,等待一个或多个文件描述符“准备好”用于某种类型的 I/O 操作(例如,可能的输入)。如果可以在不阻塞的情况下执行相应的 I/O 操作(例如 read(2)),则认为文件描述符已准备就绪。

      所以至少根据手册,如果有任何可用数据,它会立即返回。

      【讨论】:

      • 当然,“立即”仍然取决于调度程序决定在系统调用返回时执行的任何操作 - 但除非上下文切换,它应该立即返回。但是,在一个非常繁忙的系统上,它可能仍会出现阻塞。
      • @lanzz 手册页还说:“将监视 readfds 以查看字符是否可用于读取(更准确地说,查看读取是否不会阻塞;特别是文件描述符也是准备好文件结尾)”。这让我觉得它只是在等待新数据触发,其中可能包括文件结尾。
      • 如果描述符在eof,它将阻塞;它会将描述符返回为可读,而读取将返回0字节而不阻塞,这仍然与上面的mansn-p(“就绪”==“操作不会阻塞”)一致。
      猜你喜欢
      • 1970-01-01
      • 2012-02-11
      • 1970-01-01
      • 2011-07-18
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-27
      相关资源
      最近更新 更多