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

时间:2016-08-26 19:24:41

标签: linux io epoll epollet

是否可以在单次级别 - 触发模式下使用epoll
我搜索时找不到任何关于它的信息;似乎每个人都使用边缘触发模式。

2 个答案:

答案 0 :(得分:3)

当选择了EPOLLONESHOT标志并且你已经为套接字拉了一个事件时,那么套接字将不会像许多人想的那样从epoll中删除,但是它的事件被禁用了。您可以使用epoll_ctl / EPOLL_CTL_MOD再次启用它们。

EPOLLONESHOT行为很方便的示例是当您从套接字读取可用数据到缓冲区时。该缓冲区将被独立清空,但在它不为空之前,您必须禁用套接字事件,即使套接字有其他数据。然后在使用和清空缓冲区后,您可以重新启用套接字。

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

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

    1. 由于3K数据仍然存在于内核缓冲区中,因此会再次触发该事件。
    2. 边缘触发的EPOLLONESHOT:

      1. 它不会再次触发可用数据的事件。您必须通过阅读并等待EAGAIN / EWOULDBLOCK
      2. 对其进行测试

答案 1 :(得分:1)

如果你想让epoll停止侦听套接字,你应该使用EPOLLONESHOT。如果您确实使用了EPOLLONESHOT,则必须在该套接字上的epoll信号之后将套接字添加回epoll。因此EPOLLONESHOT不是EPOLLET。您可以在没有EPOLLET的情况下使用EPOLLONESHOT,但它可能效率不高。如果你同时使用这两个标志,那么你将不得不使用非阻塞套接字,并且只在recv时向epoll添加一个套接字并发送带有EAGAIN错误的返回。有关详细信息,请参阅手册页。