epoll边缘触发选项的目的是什么?

Dan*_*Dan 56 c sockets epoll

来自epoll的手册页:

epoll is a variant of poll(2) that can be used either as an edge-triggered
or a level-triggered interface
Run Code Online (Sandbox Code Playgroud)

什么时候会使用边缘触发选项?手册页给出了一个使用它的示例,但我不明白为什么在示例中有必要.

Jam*_*lin 101

当FD变为读或写时,您可能不一定想立即读取(或写入)所有数据.

只要FD保持准备好,等级触发的epoll就会一直唠叨你,而边缘触发不会再次打扰你,直到下次你得到一个EAGAIN(因此编码更复杂,但可以更高效,取决于什么你需要这样做).

假设您正在从资源写入FD.如果您注册了您对FD的兴趣,请将其作为级别触发的写入准备就绪,您将不断收到FD已准备好写入的通知.如果资源尚未可用,那就是浪费唤醒,因为无论如何你都不能再写了.

如果您要将其添加为边缘触发,则会收到FD写入就绪的通知,然后当其他资源准备就绪时,您可以尽可能多地写入.然后,如果write(2)返回EAGAIN,则停止写入并等待下一个通知.

这同样适用于阅读,因为您可能不希望在准备好做任何想做的事情之前将所有数据拉入用户空间(因此必须缓冲它等等).使用边缘触发的epoll,当它准备好阅读时,你会被告知,然后可以记住这一点,然后"当时"进行实际阅读.

  • ET在多核计算机上的多线程服务器上也特别好用.您可以为每个核心运行一个线程,并让所有这些线程在同一个epfd上调用epoll_wait.当数据进入fd时,将只唤醒一个线程来处理它. (25认同)
  • @Emanuele - 确认,ET保证只有一个线程被唤醒. (7认同)
  • @windfinder纠正我,如果我错了,但在LT模式下多个线程_might_并行唤醒同一个FD/SD,只要有数据.使用ET _one only_通知是在数据存在时为FD/SD设置的,因此只有一个线程会收到这样的通知; 其他线程可能会获得相同FD/SD的通知,但仅当原始线程有读取/写入_all_数据的通知时; 你可以想象用ET编写MT epoll进程更容易.希望这可以帮助. (5认同)
  • 这种边缘触发的行为是否可以安全地抵抗竞争条件,例如,如果数据在`read`失败后使用`EAGAIN`但在调用`epoll`之前变得可用? (3认同)

小智 9

在我的实验中,ET不保证只有一个线程被唤醒,尽管它通常只唤醒一个线程.EPOLLONESHOT标志就是为了这个目的.

  • `man 7 epoll`:由于即使使用边缘触发的`epoll`,也可以在收到多个数据块时生成多个事件,调用者可以选择指定`EPOLLONESHOT`标志,告诉`epoll`禁用收到带有'epoll_wait(2)`的事件后的关联文件描述符.当指定`EPOLLONESHOT`标志时,调用者有责任使用`epoll_ctl(2)`和'EPOLL_CTL_MOD`重新安装文件描述符. (3认同)