5

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

4

2 回答 2

8

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
于 2017-09-10T16:31:20.617 回答
1

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

于 2017-01-29T02:04:21.583 回答