Linux Man на русском

  User    Syst    Libr    Device    Files    Other    Admin  



   epoll_wait - ждать события ввода/вывода на файловом дескрипторе

epoll_wait(2) ждать события ввода/вывода на файловом дескрипторе

Other Alias

epoll_pwait


ОБЗОР

#include <sys/epoll.h>


int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *sigmask);


ОПИСАНИЕ

Системный вызов epoll_wait() ожидает события на экземпляре epoll(7), на который указывает файловый дескриптор epfd. Область памяти, на которую указывает events, будет содержать события, доступные для вызываемого. Вызов epoll_wait() может вернуть до maxevents событий. Параметр maxevents должен быть больше нуля.

В аргументе timeout указывается количество миллисекунд, на которые блокируется epoll_wait(). Вызов будет заблокирован пока:

  • событие не будет доставлено в файловый дескриптор;
  • вызов не прервётся обработчиком сигнала;
  • не истечёт время ожидания.

    Заметим, что интервал timeout будет округлён в соответствии с точностью системных часов, а задержки ядерного планирования приведут к тому, что интервал блокировки может быть немного больше. Если присвоить timeout значение -1, то epoll_wait() блокируется навсегда; если значение timeout равно 0, то epoll_wait() сразу завершает работу, даже если никаких событий не произошло.

    Структура struct epoll_event определена так:

    typedef union epoll_data {
        void    *ptr;
        int      fd;
        uint32_t u32;
        uint64_t u64;
    } epoll_data_t;
    struct epoll_event {
        uint32_t     events;    /* События epoll */
        epoll_data_t data;      /* Переменная для данных пользователя */
    };
    

    Поле data в каждой возвращаемой структуре будет содержать данные пользователя, установленные с помощью epoll_ctl(2) (EPOLL_CTL_ADD, EPOLL_CTL_MOD), а в поле events будет содержаться битовое поле возвращаемого события.

    epoll_pwait()

    Отношения между epoll_wait() и epoll_pwait() аналогичны родству select(2) и pselect(2): как pselect(2), epoll_pwait() позволяет приложению безопасно ждать, пока файловый дескриптор не станет готов или пока не будет получен сигнал.

    Вызов epoll_pwait():

        ready = epoll_pwait(epfd, &events, maxevents, timeout, &sigmask);
    
    эквивалентен атомарному выполнению следующих вызовов:
        sigset_t origmask;
        pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
        ready = epoll_wait(epfd, &events, maxevents, timeout);
        pthread_sigmask(SIG_SETMASK, &origmask, NULL);
    

    Аргумент sigmask может быть равен NULL --- в этом случае epoll_pwait() эквивалентен epoll_wait().


    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

    При нормальном выполнении epoll_wait() возвращает количество файловых дескрипторов, готовых для запросов ввода-вывода, или ноль, если ни один файловый дескриптор не стал готов за отведённые timeout миллисекунд. При возникновении ошибки epoll_wait() возвращает -1 и устанавливает errno в соответствующее значение.


    ОШИБКИ

    EBADF Значение epfd не является правильным файловым дескриптором.

    EFAULT Память, указанная events, недоступна на запись из-за прав доступа.

    EINTR Вызов был прерван обработчиком сигнала до возникновения любого из запрошенных событий или истечения timeout; см. signal(7).

    EINVAL epfd не является файловым дескриптором epoll, или maxevents меньше или равно нулю.

    ВЕРСИИ

    Вызов epoll_wait() был добавлен в ядро версии 2.6. В glibc соответствующая функция появилась в версии 2.3.2.

    Вызов epoll_pwait() был добавлен в ядро Linux 2.6.19. В glibc соответствующая функция появилась в версии 2.6.


    СООТВЕТСТВИЕ СТАНДАРТАМ

    Вызов epoll_wait() есть только в Linux.


    ЗАМЕЧАНИЯ

    Пока одна нить блокирована в вызове epoll_pwait(), в другой нити возможно добавить файловый дескриптор, который будет ожидаться экземпляром epoll. Как только новый файловый дескриптор станет готовым, это разблокирует вызов epoll_wait().

    Обсуждение того, что может случиться, если файловый дескриптор в экземпляре epoll отслеживается epoll_wait() и при этом закрывается в другой нити, смотрите в select(2).

    ДЕФЕКТЫ

    В ядрах до версии 2.6.37, если значение timeout больше чем приблизительное LONG_MAX / HZ секунд, то оно воспринимается как -1 (т.е., бесконечность). То есть, например, в системе, где sizeof(long) равно 4 и значение ядра HZ равно 1000, задержка более 35,79 минут считается бесконечностью.

    Отличия между библиотекой C и ядром

    Ядерный системный вызов epoll_pwait() имеет шестой аргумент, size_t sigsetsize, в котором указывается размер аргумента sigmask в байтах. В обёрточной функции glibc epoll_pwait() в этом аргументе передаётся постоянная величина (равная sizeof(sigset_t)).