Обратите внимание: ни одна из этих методик не занимается непосредственным вводом/выводом. Они всего лишь сообщают нам о готовности файлового дескриптора. Для выполнения чтения или записи нужно использовать дополнительные системные вызовы.

Одной из моделей, не описанной в этой главе, является POSIX AIO (асинхронный ввод/вывод), который позволяет процессу помещать операции чтения или записи файла в очередь и затем оповещает его об их завершении. Преимущество POSIX AIO заключается вот в чем: исходный вызов возвращается без промедления, так что процессу не нужно ждать, когда данные будут переданы ядру или операция будет завершена. Это позволяет процессу выполнять другие задачи параллельно с вводом/выводом (возможно даже размещение в очереди дополнительных запросов на чтение или запись). POSIX AIO обеспечивает заметный прирост производительности для определенной категории приложений. В современных версиях Linux этот интерфейс реализован на основе потоков в рамках библиотеки glibc. На момент написания книги ведется работа над реализацией POSIX AIO на уровне ядра, что должно обеспечить лучшее масштабирование. Описание данного интерфейса можно найти в книгах [Gallmeister, 1995] и [Robbins & Robbins, 2003].

Выбор подходящей методики

Далее в этой главе мы постараемся взвешивать причины, которые могут подтолкнуть нас к использованию той или иной методики. А пока что перечислим несколько основных моментов.

• select() и poll() — устоявшиеся системные вызовы; они присутствуют в UNIX-системах на протяжении многих лет. Их основным преимуществом перед остальными методиками выступает портируемость на другие платформы. Главный же недостаток заключается в проблемах с масштабированием при мониторинге множества (сотен или тысяч) файловых дескрипторов.

• Ключевым преимуществом программного интерфейса epoll является то, что он позволяет приложению эффективно следить за большим количеством дескрипторов. Главный его недостаток — он поддерживается только в Linux.

Ряд реализаций UNIX предоставляют (нестандартные) механизмы, похожие на epoll. Например, в Solaris существует специальный файл /dev/poll (страница poll(7d) руководства), а в некоторых разновидностях BSD доступен программный интерфейс kqueue (представляющий собой более универсальную систему мониторинга, чем epoll). Эти два механизма кратко описаны в книге [Stevens et al., 2004]; подробную информацию об интерфейсе kqueue можно найти в книге [Lemon, 2001].

• По аналогии с интерфейсом epoll ввод/вывод на основе сигналов позволяет приложениям более эффективно отслеживать большое количество файловых дескрипторов. Вместе с тем epoll имеет несколько заметных преимуществ:

• позволяет избежать трудностей, связанных с сигналами;

• позволяет выбирать нужный способ мониторинга (например, отслеживать готовность для чтения или для записи);

• позволяет выбирать, когда будут генерироваться уведомления — при изменении уровня или при достижении граничного значения (см. подраздел 59.1.1).

Кроме того, чтобы в полной мере воспользоваться преимуществами ввода/вывода на основе сигналов, необходимо применять функции, которые доступны только в Linux и отсутствуют в других системах; то есть данная методика ничем не лучше epoll в плане портируемости.

Ввиду того что вызовы select() и poll() имеют лучшую портируемость, а ввод/вывод на основе сигналов и интерфейс epoll обладают более высокой производительностью, в ряде случаев для мониторинга событий, связанных с файловыми дескрипторами, имеет смысл написать отдельный уровень абстракции. Это позволит использовать интерфейс epoll (или аналогичный) в системах, которые его поддерживают, а в остальных случаях прибегать к вызовам select() или poll().

Библиотека libevent представляет собой слой абстракции для мониторинга событий, относящихся к файловым дескрипторам. Она была перенесена на множество UNIX-систем. Позволяет прозрачно задействовать любые методики, описанные в этой главе: вызовы select() и poll(), ввод/вывод на основе сигналов, интерфейс epoll, а также файл /dev/poll в Solaris и интерфейс kqueue в системах семейства BSD (таким образом, libevent служит примером использования всех этих механизмов). Библиотека libevent написана Найлсом Провосом и доступна на http://libevent.org/.

59.1.1. Уведомления, срабатывающие по уровню или фронту

Прежде чем переходить к подробному обсуждению различных альтернативных механизмов ввода/вывода, необходимо выделить два способа определения готовности файлового дескриптора:

• срабатывание по уровню — файловый дескриптор считается готовым, если позволяет выполнить системный вызов ввода/вывода без блокировки;

• срабатывание по фронту — уведомление предоставляется в случае, если с момента последней проверки в файловом дескрипторе обнаружена новая активность (например, новый ввод).

Перейти на страницу:

Похожие книги