#c #macos #kqueue
#c #macos #kqueue
Вопрос:
Я пытаюсь понять вариант использования 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, amp;ev, 1, NULL, 0, NULL);
...
struct kevent ev = {
.ident = fd,
.filter = EVFILT_READ,
.flags = EV_ENABLE
};
kevent(KQueue, amp;ev, 1, amp;ev, 1, NULL);
Теперь, когда последний вызов kevent()
возвращает, ev.udata
NULL
вместо somePtr
. Если kevent()
обновляет udata
указатель, даже если EV_ADD не установлен, вместо того, чтобы просто включить событие, в чем причина, по которой вам разрешено добавлять отключенное событие?
Ответ №1:
Другой вариант использования для EV_ENABLE
— в сочетании с EV_DISPATCH
. Это необходимо в многопоточном сценарии, где у вас есть несколько потоков, ожидающих событий в kevent()
вызове. Когда происходит событие, без EV_DISPATCH
которого все ваши потоки будут разбужены одним и тем же событием, вызывающим проблему с громоподобным стадом. При EV_DISPATCH
этом событие доставляется в один поток и сразу после этого отключается (т. е. атомарно с точки зрения пользовательского пространства). Затем поток обрабатывает событие и может повторно включить его.
Ответ №2:
-
kqueue
не обновлялсяudata
. ВЫ обновилиudata
, оставив его неинициализированным. Вы регистрируете фильтр с новыми значениями. Смыслudata
в том, чтобы пересечь ядро с ним. Вы можете сохранить свой собственный указательuserland
. -
Смысл отключения события заключается в том, что вы хотите, чтобы оно возвращалось при другом вызове, или что вы не хотите,
kqueue
чтобы оно возвращалось при его запуске, но в другое время.