8

我已经从 select() 中获得了用于读取的信号套接字,但是 recv call() 没有到达任何数据,而是返回 -1 并带有 errno==EAGAIN。

我可以允许没有其他线程接触套接字。

我认为这种行为是不正确的。如果发生来自另一方的后续关闭,我可以期望来自 recv 的返回值 0(优雅关闭)或其他错误代码,但不是 EAGAIN,因为我认为这意味着数据将在未来到达。

我在这里找到了一些关于该问题的先前线程,但没有解决方案。

这种行为在 Ubuntu Linux Oneric 或其他最后的 Linux 发行版上发生在我身上,然后来自此处发布的链接的信息

对于 3.0.0 内核或最新的 2.6.x,它将在内核中修复是不正确的

有谁知道它为什么会发生以及如何避免这种不需​​要的行为?

4

2 回答 2

6

Select() 将套接字报告为可读并不意味着有东西要读;这意味着读取不会阻塞。读取可以返回 -1 或 0,但不会阻塞

更新:

select返回可读后:如果read()返回-1,检查errno。EAGAIN/EWOULDBLOCK 和 EINTR 是需要特别处理的值:主要是通过重新发出 read(),但您可能相信选择循环在下一次返回可读。

如果涉及多个线程,事情可能会变得更加困难。

于 2011-11-24T11:58:42.993 回答
1

我遇到了同样的问题,但使用了 epoll。我注意到,只要系统重用已经关闭的套接字的 FD 编号,就会发生这种情况。经过一些研究,我注意到这种行为是由于在对它们进行 epoll 时关闭套接字引起的。尝试在关闭套接字时避免在套接字上运行 select - 这可能会有所帮助。

于 2013-09-01T16:16:12.847 回答