Описание тега epoll
API epoll состоит из трех функций:
- epoll_create создает новый экземпляр epoll и возвращает файловый дескриптор, который ссылается на него. Этот дескриптор может использоваться с другими функциями epoll и может быть добавлен в другой экземпляр epoll.
- epoll_ctl позволяет добавлять и удалять файловые дескрипторы (сокеты, каналы, eventfd, timerfd, signalfd и epoll) в набор отслеживаемых дескрипторов epoll, а также изменять флаги существующих дескрипторов.
- epoll_wait вернет до maxevents событий в очереди. Если доступных событий нет, возвращается ноль. Если задан тайм-аут и нет доступных событий, epoll_wait будет блокироваться на время тайм-аута (значение -1 означает навсегда).
Концептуальная идея, лежащая в основе API, заключается в том, что приложения обычно имеют определенный набор дескрипторов, который редко, если вообще когда-либо, изменяется, но который необходимо многократно проверять на предмет готовности. Кроме того, обычно готовых дескрипторов гораздо меньше, чем открытых. Поэтому epoll отделяет копирование списка дескрипторов для наблюдения от фактического просмотра и уведомляет зарегистрированных слушателей вместо повторения списка дескрипторов.
Работа в режиме с запуском по уровню (по умолчанию) проста, поскольку он идентичен принципу работы опроса / выбора. Пока ресурс готов (например, пока остаются данные для чтения), каждый вызов epoll_wait будет возвращать событие.
Работа в режиме запуска по фронту (флаг EPOLLET) более сложна, подвержена ошибкам, непоследовательно документирована и непоследовательно реализована. Вepoll(7)
, это объясняется в терминах чтения частичных данных, вызывающих блокировку следующего вызова epoll_wait до тех пор, пока не появятся новые данные, но не пока некоторые данные остаются в буферах. Поэтому рекомендуется использовать неблокирующие дескрипторы и чтение, пока не будет получен EAGAIN.
Согласно интерфейсу программирования Linux, режим с запуском по фронту сообщает только о событиях, которые произошли с момента последнего вызова epoll_wait.
На самом деле, это сочетание обоих (т.е. и чтение, и epoll_wait сбрасывают статус на "не готов"), и он не работает, как указано в отношении нескольких экземпляров epoll, прослушивающих один и тот же сокет, или нескольких потоков, ожидающих одного и того же Экземпляр epoll (наблюдается в ядре 2.6.38 с timerfd и eventfd). Хотя предполагается, что epoll сигнализирует всем официантам о прибытии события, в режиме запуска по фронту он сигнализирует только одному официанту.