一次性*级别* – 触发epoll():EPOLLONESHOT是否意味着EPOLLET?

是否可以在单触式水平触发模式下使用epoll
search时找不到任何信息; 似乎每个人都使用边缘触发模式。

如果你想epoll停止在套接字上听,你应该使用EPOLLONESHOT。 如果你使用EPOLLONESHOT,那么你必须在套接字上的epoll信号之后将套接字添加回epoll。 因此EPOLLONESHOT不是EPOLLET。 您可以使用EPOLLONESHOT而不使用EPOLLET,但可能效率不高。 如果你使用两个标志,那么你将不得不使用非阻塞套接字,并且只能在recv中添加一个套接字到epoll,并且发送带有EAGAIN错误的返回。 详情请参阅手册页。

EPOLLONESHOT标志被选中,并且你已经为一个套接字拉了一个事件时,套接字将不会从epoll中被移除,因为很多人认为它的事件被禁止了。 您可以使用epoll_ctl / EPOLL_CTL_MOD再次启用它们。

EPOLLONESHOT行为方便的一个例子就是当你将一个套接字中的可用数据读入缓冲区。 该缓冲区将被单独清空,但是,如果不是空的,则必须禁用套接字事件,即使套接字具有附加数据。 然后在缓冲区被使用和清空后,您可以重新启用套接字。

只有当您重新启用套接字时,边缘触发和电平触发的“一次性”行为之间的区别才会出现。 一个例子:

  1. 套接字接收7K数据(现在它存储在内核缓冲区中)
  2. 您等待输入事件,然后套接字事件由于EPOLLONESHOT而被禁用。
  3. 您将4K读入应用程序级缓冲区。
  4. 稍后,应用程序缓冲区将被使用并清空。 您使用epoll_ctl / EPOLL_CTL_MOD重新启用套接字。

级别触发EPOLLONESHOT:

  1. 由于3K数据仍然存在于内核缓冲区中,所以事件再次被触发。

边缘触发EPOLLONESHOT:

  1. 它不会再为可用数据触发事件。 你必须通过阅读测试它,并等待EAGAIN / EWOULDBLOCK