当 epoll 发出活动信号时,recv() 调用怎么会阻塞

How could a recv() call block when epoll has signalled activity?

本文关键字:调用 怎么会 recv epoll 活动 信号      更新时间:2023-10-16

我的应用程序类似于libevent,使用epoll(在级别触发模式下)来检测I/O活动并调用回调来处理它。

我最近发现我的TCP/IP套接字正在阻塞,这是一个意外,但我仍然不希望recv()调用阻止epoll报告为已挂起的读取活动。即使套接字有错误,recv()肯定会回来告诉我。

我对此有什么误解?
在这种情况下,什么样的网络状况会导致recv()阻塞?

从 Linux 中选择手册页:

在 Linux 下,select() 可能会将套接字文件描述符报告为"ready 用于阅读",而随后的读取阻止。 这 例如,当数据到达但经过检查时可能发生 校验和错误,被丢弃。 可能还有其他 文件描述符被虚假报告为 准备。 因此O_NONBLOCK,在应该 不阻止。

是的,我知道 epoll() 与 select() 不同,但我怀疑相同的基础条件适用于两者)

我认为如果您真的想避免阻塞,唯一安全的方法是将套接字设置为非阻塞模式。

如果您使用 Epoll 轮询 EPOLLIN 事件,则在此之后的 recv 调用应立即返回。此外,我希望您正在使用非阻塞套接字。如果要查找错误,则可以查找 EPOLLERR 事件。如果套接字在 epoll 信号后关闭,则 recv 应该失败。epoll_wait、epoll_ctl和套接字创建的代码片段将有助于调试问题。