Какова цель kqueue EV_ENABLE и EV_DISABLE
Я пытаюсь понять сценарий использования EV_DISABLE и EV_ENABLE в kqueue.
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 не установлен, вместо того, чтобы просто включить событие, в чем причина того, что вы можете добавить отключенное событие?
2 ответа
kqueue
не обновлялсяudata
, ВЫ обновилиudata
оставив его неинициализированным. Вы регистрируете фильтр с новыми значениями. Точкаudata
это пересечь ядро с ним. Вы можете держать свой собственный указатель вuserland
,Смысл отключения события в том, что вы хотите, чтобы оно было возвращено при другом вызове, или что вы не хотите вызывать
kqueue
чтобы вернуться, когда он срабатывает, но в другое время.
Еще один вариант использования для EV_ENABLE
в сочетании с EV_DISPATCH
, Это необходимо в многопоточном сценарии, когда у вас есть несколько потоков, ожидающих события в kevent()
вызов. Когда происходит событие, без EV_DISPATCH
все ваши потоки будут разбужены одним и тем же событием, вызывающим проблему грома в стаде. С EV_DISPATCH
событие доставляется в один поток и сразу после этого отключается (т.е. атомарно с точки зрения пространства пользователя). Затем поток обрабатывает событие и может повторно включить его.