select() 标记一个FD可读,但是没有数据可读

select() 标记一个FD可读,但是没有数据可读

我在服务器代码中遇到一个问题,即使将其标记为可读accept(),对侦听套接字的调用偶尔也会阻塞。select()我的理解是,这种情况应该不会经常发生(如果有的话),但我不确定当套接字“可读”时是否有 POSIX 标准保证数据可用。我目前正在调查我的代码逻辑是否有错误,但想知道是否有人有此类问题的经验,并且知道需要发生什么类型的情况才会出现这种情况?谢谢。

答案1

这是正确的行为。如果您accept()在 a 之后执行 an 操作,则无法确定连接是否仍位于接受队列中,select()因为该连接可能已被发起方终止或被另一个接受进程占用。从man 2 accept

SIGIO 在传递 a 或 select(2)poll(2)、 或 返回可读性事件后,可能并不总是有连接等待, epoll(7)因为该连接可能已被异步网络错误或accept()调用之前的另一个线程删除。如果发生这种情况,则调用将阻塞等待下一个连接到达。为了确保accept()永远不会阻塞,传递的套接字sockfd需要设置O_NONBLOCK标志(请参阅 参考资料socket(7))。

相关内容