Kqueue — масштабируемый интерфейс уведомлений о событиях, представленный в FreeBSD 4.1 в июле 2000 года, [1] [2] также поддерживаемый в NetBSD , OpenBSD , DragonFly BSD и macOS . Kqueue был изначально создан в 2000 году Джонатаном Лемоном, [1] [2] затем участвовавшим в работе FreeBSD Core Team . Kqueue позволяет программному обеспечению, такому как nginx, решать проблему c10k . [3] [4] Термин «kqueue» относится к его функции «очереди событий ядра» [1] [2]
Kqueue обеспечивает эффективные входные и выходные конвейеры событий между ядром и пользовательским пространством . Таким образом, можно изменять фильтры событий, а также получать ожидающие события, используя только один системный вызов для kevent(2)
каждой итерации основного цикла событий . Это контрастирует со старыми традиционными системными вызовами опроса, такими как poll(2)
и , select(2)
которые менее эффективны, особенно при опросе событий на многочисленных файловых дескрипторах.
Kqueue не только обрабатывает события дескриптора файла , но и используется для различных других уведомлений, таких как мониторинг изменений файла , сигналы , события асинхронного ввода-вывода (AIO), мониторинг изменения состояния дочернего процесса и таймеры , которые поддерживают разрешение в наносекундах . Кроме того, kqueue предоставляет способ использования определяемых пользователем событий в дополнение к тем, которые предоставляются ядром.
Некоторые другие операционные системы , которые традиционно поддерживали только более эффективные альтернативы опроса select(2)
, poll(2)
в настоящее время также предоставляют их, например, epoll в Linux и порты завершения ввода-вывода в Windows и Solaris .
libkqueue
представляет собой реализацию пользовательского пространстваkqueue(2)
, которая транслирует вызовы в собственный механизм событий бэкэнда операционной системы. [5]
Прототипы и типы функций можно найти в sys/event.h
. [6]
int kqueue ( void );
Создает новую очередь событий ядра и возвращает дескриптор.
int kevent ( int kq , const struct kevent * changelist , int nchanges , struct kevent * eventlist , int nevents , const struct timespec * timeout );
Используется для регистрации событий в очереди, затем ожидания и возврата любых ожидающих событий пользователю. В отличие от epoll , kqueue использует ту же функцию для регистрации и ожидания событий, и несколько источников событий могут быть зарегистрированы и изменены с помощью одного вызова. Массив changelist
может использоваться для передачи изменений (изменение типа событий для ожидания, регистрация новых источников событий и т. д.) в очередь событий, которые применяются до начала ожидания событий. nevents
— это размер предоставленного пользователем eventlist
массива, который используется для получения событий из очереди событий.
EV_SET ( kev , ident , filter , flags , fflags , data , udata );
Макрос, используемый для удобной инициализации объекта struct kevent
.
Независимые от ОС библиотеки с поддержкой kqueue:
Эквивалент Kqueue для других платформ:
kqueue
также могут уведомлять о готовности файлового дескриптора выполнить операцию ввода-вывода.