“特殊” epoll标志如何与kqueue对应?

时间:2018-08-10 20:03:57

标签: nonblocking epoll kqueue epollet kevent

我正在努力在epoll和kqueue标志(特别是EPOLLONESHOT EPOLLET EPOLLEXCLUSIVE和EV_CLEAR / EV_DISPATCH / EV_ONESHOT)之间进行比较。我是第一次调查这个队列。我只有epoll经验。

EV_DISPATCH

感觉就像EPOLLEXCLUSIVE和EPOLLONESHOT标志的混合;来自kqueue文档:

EV_DISPATCH  Disable the event source immediately after delivery of an
             event.  See EV_DISABLE above.
EV_DISABLE   Disable the event so kevent()  will not return it.  The fil-
             ter itself is  not disabled.

如果至少有一个为这个事件轮询的kqueue实例,我是否正确地理解了有关该事件已发出信号然后立即将其丢弃的文档?也就是说,如果我们在两个队列上轮询一个套接字以获取EVFILT_READ,则只有一个会接收到它,然后,直到用EVFILT_ENABLE设置了同一事件,即使新数据传入了套接字,也不会再发生任何事件。 ?

EV_CLEAR

好像它接近EPOLLET;来自kqueue文档:

EV_CLEAR      After the event is retrieved by the user, its state is
              reset.  This is useful for filters which report state tran-
              sitions instead of the current state.  Note that some fil-
              ters may automatically set this flag internally.

因此,例如,给定具有EVFILT_READ的相同套接字,同时轮询该套接字的所有kqueue将通过EVFILT_READ唤醒。但是,如果未读取所有数据(即直到EAGAIN),则不会再报告任何事件。当且仅当读取所有数据并且并且只有新数据到达时,才会触发新的EVFILT_READ事件。正确吗?

EV_ONESHOT

看起来它映射到EPOLLONESHOT;来自kqueue文档:

EV_ONESHOT   Causes the event to return only the first occurrence of the
             filter being triggered.  After the user retrieves the  event
             from the kqueue, it is deleted.

问题

那么,这些问题:

  1. 我的理解正确吗?与epoll相比,我是否理解这些特殊标志?文档对我来说似乎有点棘手;也许问题在于我以前只使用过epoll,还没有玩过kqueue。
  2. 能否请您提供良好的资源或示例来了解kqueue技术?如果它不像Boost.Asio这样复杂,那就太好了;这些资源也可以用C编写。
  3. 这些标志可以组合在一起吗?例如,EPOLLONESHOT不能与EPOLLEXCLUSIVE结合使用,但是EV_DISPATCH似乎恰好位于这些标志之间的中间位置。

谢谢您的帮助!

参考

kqueue(2): FreeBSD System Calls Manual

epoll(7): Linux Programmer's Manual

epoll_ctl(7): Linux Programmer's Manual

1 个答案:

答案 0 :(得分:0)

  1. EV_CLEAR不等于EPOLLET,例如一些侦听套接字具有5个挂起的连接,并且您不会消耗所有连接(accept直到EAGAIN),然后使用EV_CLEAR,您将不会获得EVFILT_READ事件从kevent直到出现第6个连接。

  2. EPOLLEXCLUSIVE用于CPU绑定,与EV_DISPATCH无关。

  3. EV_ONESHOT表示在触发特定事件后删除knote,而EV_DISPATCH仅将其禁用。

  4. 如果将一个套接字fd注册到多个队列,则在触发事件时广播该事件。

  5. EV_ONESHOT几乎等于EPOLLONESHOT,在不同线程需要使用相同kqueue fd调用kevent的情况下很有用。