Какова цель 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 ответа

Решение
  1. kqueue не обновлялся udata, ВЫ обновили udata оставив его неинициализированным. Вы регистрируете фильтр с новыми значениями. Точка udata это пересечь ядро ​​с ним. Вы можете держать свой собственный указатель в userland,

  2. Смысл отключения события в том, что вы хотите, чтобы оно было возвращено при другом вызове, или что вы не хотите вызывать kqueue чтобы вернуться, когда он срабатывает, но в другое время.

Еще один вариант использования для EV_ENABLE в сочетании с EV_DISPATCH, Это необходимо в многопоточном сценарии, когда у вас есть несколько потоков, ожидающих события в kevent() вызов. Когда происходит событие, без EV_DISPATCHвсе ваши потоки будут разбужены одним и тем же событием, вызывающим проблему грома в стаде. С EV_DISPATCHсобытие доставляется в один поток и сразу после этого отключается (т.е. атомарно с точки зрения пространства пользователя). Затем поток обрабатывает событие и может повторно включить его.

Другие вопросы по тегам