我试图了解 kqueue 中 EV_DISABLE 和 EV_ENABLE 的用例。
int KQueue = kqueue();
struct kevent ev = {
.ident = fd,
.filter = EVFILT_READ,
.flags = EV_ADD | EV_DISABLE,
.udata = somePtr
};
kevent(KQueue, &ev, 1, NULL, 0, NULL);
...
struct kevent ev = {
.ident = fd,
.filter = EVFILT_READ,
.flags = EV_ENABLE
};
kevent(KQueue, &ev, 1, &ev, 1, NULL);
现在,当对 kevent()
的最后一次调用返回时,ev.udata
是 NULL
而不是 somePtr
。如果 kevent()
更新了 udata
指针,即使没有设置 EV_ADD,而不是仅仅启用事件,允许您添加禁用事件的原因是什么,那么呢?
EV_ENABLE
的另一个用例是与 EV_DISPATCH
结合使用。这在您有多个线程等待 kevent()
调用中的事件的多线程场景中是必需的。当事件发生时,如果没有 EV_DISPATCH
,您的所有线程都会在同一事件上被唤醒,从而导致雷群问题。使用 EV_DISPATCH
,事件被传送到一个线程并在之后立即被禁用(即,从用户空间的角度来看是原子的)。然后线程处理该事件并可能重新启用它。
我是一名优秀的程序员,十分优秀!