我在服务器代码中遇到一个问题,即使将其标记为可读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)
)。