Когда событие регистрируется с помощью kqueue
, предоставляется идентификатор, относящийся к этому типу события; например, дескриптор файла используется для идентификации файла для просмотра
int kq;
struct kevent ke;
kq = kqueue();
fd = open(argv[1], O_RDONLY);
EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD, NOTE_DELETE | NOTE_RENAME, 0, NULL);
kevent(kq, &ke, 1, NULL, 0, NULL);
while (1) {
kevent(kq, NULL, 0, &ke, 1, NULL);
/* respond to file system event */
}
Теперь, если мне также нужно реагировать на другие типы событий, такие как сигналы, нам нужен новый экземпляр kqueue, чтобы избежать конфликта с аргументом ident
для kevent()
.
kq_sig = kqueue();
struct kevent ke_sig;
/* set the handler and ignore SIGINT */
signal(SIGINT, SIG_IGN);
EV_SET(&ke_sig, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
kevent(kq_sig, &ke_sig, 1, NULL, 0, NULL);
while (1) {
kevent(kq_sig, NULL, 0, &ke_sig, 1, NULL);
/* respond signals */
}
Наблюдение за несколькими типами событий, по-видимому, требует нескольких потоков, которые воздействуют на общее состояние (например, получение сигнала может закрыть дескриптор файла).
Есть ли более общий механизм отправки сообщения из одного потока в другой с помощью kqueue? В некоторых случаях я могу представить себе включение и отключение фильтра как средство запуска другого события по фронту.