• F_OWNER_PID — поле pid содержит идентификатор процесса, который будет получать сигналы о возможности ввода/вывода.
• F_OWNER_TID — поле pid содержит идентификатор потока, который будет получать сигналы о возможности ввода/вывода. Идентификатор, хранящийся в поле pid, представляет собой значение, возвращаемое вызовом clone() или gettid().
Операция F_GETOWN_EX выполняет действие, обратное F_GETOWN_EX. Она использует структуру f_owner_ex, на которую указывает третий аргумент вызова fcntl(), чтобы вернуть параметры, установленные предыдущей операцией F_SETOWN_EX.
Операции F_SETOWN_EX и F_GETOWN_EX представляют идентификаторы группы процессов в виде положительных чисел, поэтому F_GETOWN_EX не имеет тех проблем, которые присущи ранее описанному флагу F_GETOWN (когда идентификаторы группы процессов меньше 4096).
По аналогии с вводом/выводом на основе мультиплексирующих системных вызовов и сигналов программный интерфейс epoll (от англ. event poll — «наблюдение за событиями») используется для контроля готовности множества файловых дескрипторов. Главные преимущества epoll перечислены ниже.
• При мониторинге большого количества файловых дескрипторов интерфейс epoll масштабируется гораздо лучше, чем вызовы select() и poll().
• Интерфейс epoll поддерживает уведомления по уровню и по фронту. Для сравнения: вызовы select() и poll() способны уведомлять лишь по уровню, а ввод/вывод на основе сигналов — только по фронту.
Интерфейс epoll и ввод/вывод на основе сигналов имеют аналогичную производительность. Хотя первый обладает некоторыми преимуществами:
• позволяет избежать сложностей, связанных с обработкой сигналов (например, переполнение очереди сигналов);
• обеспечивает лучшую гибкость при описании интересующих событий (например, можно проверять, готов ли файловый дескриптор сокета к чтению, записи или к обеим этим операциям).
Программный интерфейс epoll поддерживается только в Linux версии 2.6 и выше.
Главной структурой данных в этом интерфейсе является
• запись списка файловых дескрипторов, в отслеживании которых заинтересован текущий процесс
• предоставление списка файловых дескрипторов, готовых к вводу/выводу
Второй список дескрипторов является подмножеством первого.
Для каждого файлового дескриптора, наблюдаемого с помощью интерфейса epoll, можно указать битовую маску, определяющую события, о которых мы хотим узнавать. Эта битовая маска аналогична той, что используется для вызова poll().
Программный интерфейс epoll состоит из трех системных вызовов.
• Вызов epoll_create() создает экземпляр epoll и возвращает файловый дескриптор, который на него ссылается.
• Вызов epoll_ctl() изменяет список отслеживаемых дескрипторов, связанных с экземпляром epoll. Он позволяет добавлять новые и удалять существующие дескрипторы, а также редактировать маску, описывающую интересующие нас события.
• Вызов epoll_wait() возвращает элементы списка готовых дескрипторов, связанных с экземпляром epoll.
59.4.1. Создание экземпляра epoll: вызов epoll_create()
Системный вызов epoll_create() создает новый экземпляр epoll с изначально пустым списком интереса.
#include
int epoll_create(int
Возвращает файловый дескриптор при успешном завершении или -1 при ошибке
Аргумент size обозначает количество дескрипторов, которые мы хотим отслеживать с помощью экземпляра epoll. Это не максимальное значение, а некий ориентир; на его основе ядро будет подбирать исходный размер своих внутренних структур данных (начиная с версии Linux 2.6.8 аргумент size игнорируется, поскольку в новой реализации указанные сведения больше не нужны).
В качестве результата функция epoll_create() возвращает файловый дескриптор, ссылающийся на новый экземпляр epoll и позволяющий работать с ним в других системных вызовах данного интерфейса. Когда необходимость в этом дескрипторе пропадает, его следует закрыть стандартным способом — с помощью вызова close(). Экземпляр epoll уничтожается с закрытием последнего файлового дескриптора, который на него ссылается; притом освобождаются все связанные с ним ресурсы (в результате множественных вызовов fork() или операций дублирования, таких как dup(), на один и тот же экземпляр epoll может ссылаться сразу несколько дескрипторов).