在使用Edge Triggered和EPOLLONSHOT时,我对EPOLL有一些问题。
下面列出了简化的发言顺序。实际上,Epoll Fd监视多个文件,并通过特定线程管理一个集合。所使用的变量名称不言自明,当然,它们是集合的。为了简洁起见,省略了该部分:
1. Create epollFd
epollFd = epoll_create1(EPOLL_CLOEXEC);
2. Create events to monitor
epollEventParam.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT;
3. Add the FD to monitor and the events
epoll_ctl(epollFd, EPOLL_CTL_ADD, socketFd, &epollEventParam);
4. While loop with epoll_wait
while (1) {
noFdsEvented = epoll_wait(epollFd, epollEventsReported, maxEvents, -1);
/***************** REARM Here or after processing the events? ******/
epoll_ctl(epollFd, EPOLL_CTL_MOD, (int)epollEventsReported[i].data.fd, &epollEventParam);
/** if EPOLLIN, read until read returns EAGIN ***/
//Relevant code to read...
//After EAGAIN is returned, REARM Here instead of doing so earlier (above)?
/** if EPOLLOUT, write until write returns EAGIN ***/
//Relevant code to write...
//After EAGAIN is returned, REARM Here instead of doing so earlier (above)?
/*** If other events... process accordingly ***/
}
问题:
使用EPOLLONSHOT时,应在何时重新处理EPOLL?接收事件之后还是处理事件之后?
小学。在写入或读取时,我们会跟踪写入/读取的数据点,直到返回EAGAIN,或者如果部分读取/写入?是/否。
最初未设置EPOLLOUT。写入时,当write返回EAGAIN时,我们将EPOLLOUT添加到事件中待监测。是/否?
当FD再次触发EPOLLOUT时,我们从最后一次接收EAGAIN开始继续写入这样做,直到我们再次获得EAGAIN。然后我们到达。是/否?
如果我们部分读取而不REARM,新数据将继续到达,但不会触发任何事件。因此,如果我们部分读取,我们需要跟踪它,而不仅仅依赖事件处理程序来进行读取处理。正确的
我不能全部回答,但我可以试着回答一些。
-
小学。在写入或读取时,我们会跟踪写入/读取的数据点,直到返回EAGAIN,或者如果部分读取/写入?是/否
- 对于read/recv:您应该处理以下所有场景
- 如果您阅读/recv EAGAIN或EWOULDBLOCK。这表示没有剩余的内容可以读取/recv,您应该中断接收循环
- 您收到0个字节。这表示另一侧不再连接
- 您收到0>个字节。您已成功读取/recv数据,应该再次读取/recv
- 你不一定需要跟踪数据,而只是确保你能处理以上3种情况
- 对于read/recv:您应该处理以下所有场景
-
最初未设置EPOLLOUT。在写入时,当write返回EAGAIN时,我们将EPOLLOUT添加到要监视的事件中。是/否
- 是的。。。我相信,在最初设置EPOLLOUT的情况下,send((FD上应该发生与您在问题中描述的相同的行为。。。考虑到无论事件通知如何,您都将简单地写入FD,并且只有在收到EAGAIN/EWOULDBOCK错误时才会停止