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

从epoll的手册页:

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

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

当FD变为读取或写入准备好时,您可能不需要立即读取(或写入)所有数据。

只要FD保持准备就绪,水平触发的epoll将不停地唠叨你,而边缘触发不会再次打扰你,直到下一次你得到一个EAGAIN (所以编码更复杂,但可以更有效地取决于你需要做什么)。

假设你正在从一个资源写入一个FD。 如果您注意到您对该FD的兴趣准备就绪,可以通过电平触发,则会不断通知FD仍然准备好写入。 如果资源尚不可用,这是一个浪费唤醒,因为你不能再写任何东西。

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

这同样适用于阅读,因为在准备好做任何你想做的事情之前,你可能不想把所有的数据都拉进用户空间(因此不得不缓冲它等等)。 用边缘触发的epoll,你可以在准备好阅读的时候被告知,然后可以记住它,并且做“实时”的实际阅读。

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