在使用边缘触发和 EPOLLONESHOT 时,我对 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 ***/
}
问题:
使用 EPOLLONESHOT 时,应何时重新武装 EPOLL?收到事件后还是处理完事件后?
初级。在写入或读取时,我们会跟踪写入/读取的数据点,直到返回 EAGAIN 或部分读取/写入?是/否。
最初没有设置 EPOLLOUT。写入时,当write返回EAGAIN时,我们将EPOLLOUT添加到要监控的事件中。是/否?
当 FD 再次触发 EPOLLOUT 时,我们从上次收到 EAGAIN 的点继续写入,直到我们再次获得 EAGAIN。然后我们重新武装。是/否?
如果我们读取部分而不重新ARM,新数据将继续到达但不会触发任何事件。因此,如果我们读取部分内容,我们需要对其进行跟踪,而不是仅依赖事件处理程序进行读取处理。对?