epoll 是否保证在使用 epoll_ctl 为 EPOLLIN 注册文件后对 epoll_wait 的第一次(或正在进行的)调用,如果在 epoll_ctl 调用之前文件已经可读,则 EPOLLET 立即返回?从我对测试程序的实验来看,答案似乎是肯定的。这里有几个例子来澄清我的问题:
假设我们已经初始化了一个 epoll 文件efd
和一个文件fd
以及如下事件定义:
event.data.fd = fd;
event.events = EPOLLIN | EPOLLET;
现在考虑这种情况:
- thread1:写入数据
fd
- 线程2:
epoll_ctl (efd, EPOLL_CTL_ADD, fd, &event);
- 线程2:
epoll_wait (efd, events, MAXEVENTS, -1);
现在第 3 步中的调用会立即返回吗?根据我的经验,确实如此。这是有保证的吗?
现在考虑第二种情况,扩展第一种情况:
- thread1:写入数据
fd
- 线程2:
epoll_ctl (efd, EPOLL_CTL_ADD, fd, &event);
- 线程2:
epoll_wait (efd, events, MAXEVENTS, -1);
- 线程2:
epoll_ctl (efd, EPOLL_CTL_MOD, fd, &event);
- 线程2:
epoll_wait (efd, events, MAXEVENTS, -1);
步骤 5 中的调用是否立即返回?根据我的经验,确实如此。有保障吗?
epoll 手册页在这个问题上并不完全清楚。特别是,手册页建议您应该始终从文件中读取,直到使用边缘触发模式时返回 EAGAIN。但似乎这些评论是假设您在等待文件时没有重新注册文件。
epoll的边缘触发选项的目的是什么?是一个相关的讨论。第一个答案的前两条评论似乎证实了我看到的行为是预期的。
https://gist.github.com/3900742是一个 C 测试程序,它说明了带有管道的 epoll 的行为似乎与我描述的一样。