Знакомство с основами асинхронного программирования на * nix

В течение некоторого времени я много гуглил, чтобы узнать о различных способах достижения асинхронного программирования / поведения на машинах nix, и (как мне было известно ранее) получил подтверждение того факта, что до сих пор нет ИСТИННОГО асинхронного шаблона (параллелизм с использованием одного потока) для Linux, как это доступно для Windows (IOCP).

Ниже приведены несколько альтернатив для Linux:

  1. select / poll / epoll :: Невозможно выполнить с использованием одного потока, поскольку epoll все еще блокирует вызов. Также отслеживаемые файловые дескрипторы должны быть открыты в неблокирующем режиме.
  2. libaio :: Что я узнал, так это то, что его реализация - отстой, и его все еще основанное на уведомлении, а не на завершении, как в портах завершения ввода-вывода Windows.
  3. Boost ASIO: он использует epoll под Linux и, следовательно, не является настоящим асинхронным шаблоном, поскольку порождает потоки, которые полностью абстрагируются от пользовательского кода для достижения шаблона проектирования проактора.
  4. libevent :: Есть ли причина для этого, если я предпочитаю ASIO?

А теперь вопросы :)

  1. Каким будет лучший шаблон проектирования для написания быстрого масштабируемого сетевого сервера с использованием epoll (конечно, здесь придется использовать потоки :()
  2. Я где-то читал, что «в неблокирующем режиме можно открывать только сокеты», следовательно, epoll поддерживает только сокеты и, следовательно, не может использоваться для дискового ввода-вывода. Насколько верно приведенное выше утверждение и почему асинхронное программирование не может выполняться на дисковом вводе-выводе с помощью epoll?
  3. Boost ASIO использует одну большую блокировку вокруг вызова epoll. На самом деле я не понимал, какие могут быть последствия и как их преодолеть с помощью самого asio. Аналогичный вопрос
  4. Как я могу изменить шаблон ASIO для работы с дисковыми файлами? Есть ли рекомендуемый шаблон дизайна?

Надеюсь, что кто-нибудь также сможет ответить на все вопросы с хорошими объяснениями. Также приветствуются любые ссылки на источник, где объясняются детали реализации шаблонов проектирования epoll и AIO.


person Arunmu    schedule 08.01.2012    source источник
comment
Все select, poll и epoll имеют параметр тайм-аута, который может быть равен нулю, что приводит к немедленному возврату функций.   -  person Some programmer dude    schedule 08.01.2012
comment
Кроме того, наличие уведомлений, как в случае с aio_* функциями, является асинхронным. Вы просите, чтобы вас уведомляли, когда происходит событие, а затем продолжаете заниматься своими делами, пока ядро ​​обрабатывает ваш ввод-вывод.   -  person Some programmer dude    schedule 08.01.2012
comment
epoll_wait не обязательно является блокирующим вызовом; это зависит от переданного ему параметра тайм-аута (подробности см. в man epoll_wait).   -  person dimitri    schedule 08.01.2012
comment
Есть ли причина избегать обсуждений? Вы знаете о проблемах с производительностью?   -  person stefaanv    schedule 08.01.2012
comment
@Joachim: Да, я в курсе. Означает ли это, что я могу достичь истинного шаблона асинхронного проектирования с использованием одного потока, используя epoll с нулевым таймаутом?   -  person Arunmu    schedule 08.01.2012
comment
@stefaanv: Возможно, нужно избегать тредов, чтобы избежать проблем с гонками.   -  person Arunmu    schedule 08.01.2012
comment
@Joachim: Но все равно не подходит для обработчика завершения, поскольку он заботится о чтении и записи для меня, и я ожидаю, что он будет более эффективным, чем на основе уведомлений.   -  person Arunmu    schedule 08.01.2012
comment
Большинство серверного программного обеспечения использует select в одном потоке. Скорее всего, с ненулевым таймаутом, но использование этих функций в режиме опроса с нулевым таймаутом и в одном потоке далеко не редкость. Однако это не совсем асинхронный процесс, а опрос.   -  person Some programmer dude    schedule 08.01.2012


Ответы (2)


Boost ASIO :: Он использует epoll под Linux и, следовательно, не является настоящим асинхронным шаблоном, поскольку он порождает поток, который полностью абстрагируется от пользовательского кода для достижения шаблона проектирования проактора.

Это не так. Библиотека Asio по умолчанию использует epoll() в самых последних версиях ядра Linux. однако потоки, вызывающие io_service::run(), будут вызывать обработчики обратного вызова по мере необходимости. В библиотеке Asio есть только одно место, где поток используется для эмуляции асинхронного интерфейса, он хорошо описан в документация:

Дополнительный поток на io_service используется для имитации асинхронного разрешения хоста. Этот поток создается при первом обращении к ip::tcp::resolver::async_resolve() или ip::udp::resolver::async_resolve().

Это не делает библиотеку «не настоящим асинхронным шаблоном», как вы утверждаете, на самом деле ее название не согласуется с вами по определению.

1) Каким будет лучший шаблон проектирования для написания быстрого масштабируемого сетевого сервера с использованием epoll (конечно, здесь придется использовать потоки :()

Предлагаю использовать Boost Asio, он использует шаблон проектирования проактор.

3) Boost ASIO использует одну большую блокировку вокруг вызова epoll. На самом деле я не понимал, каковы могут быть его последствия и как их преодолеть с помощью самого asio

Реактор epoll использует мьютекс для отправки обработчиков, хотя на практике это не является большой проблемой для большинства приложений. Существуют специфические для приложений способы смягчения этого поведения, например, io_service на ЦП для использования локальности данных. См. мой ответ на аналогичный вопрос по этой теме. Это также часто обсуждается в списке рассылки Asio.

4) Как изменить шаблон ASIO для работы с дисковыми файлами? Есть ли рекомендуемый шаблон дизайна?

Как вы заметили, библиотека Asio изначально не поддерживает файловый ввод-вывод. Было несколько попыток добавить его в библиотеку, я предлагаю обсудить на список рассылки.

person Sam Miller    schedule 08.01.2012
comment
Сэм, спасибо за супер ответ. Можете ли вы также пролить свет на вопрос № 2? Я не получил четкой блокировки asio вокруг части epoll, но я постараюсь вникнуть в нее подробнее и получить ответ. - person Arunmu; 08.01.2012

Прежде всего:

получил подтверждение о том, что до сих пор не существует ИСТИННОГО асинхронного шаблона (параллелизм с использованием одного потока) для Linux, доступного для Windows (IOCP).

У вас, вероятно, есть небольшое заблуждение, что асинхронность может быть построена поверх api "опроса".

Более того, этот «реакторный» (похожий на epoll) API более мощный, чем «проакторный» API (IOCP), поскольку второй может быть реализован в терминах первого (но не наоборот).

Также некоторые операции, которые являются «истинно» асинхронными, например, дисковый ввод-вывод, некоторые другие инструменты могут быть с комбинацией сигналов, а специфичные для Linux signalfd могут обеспечить полное покрытие некоторых других случаев.

Нижняя линия. epoll действительно асинхронный ввод-вывод

person Artyom    schedule 08.01.2012
comment
Спасибо за ответ, но можете ли вы проверить последний комментарий Иоахима к моему вопросу .. его мнение иначе - person Arunmu; 08.01.2012
comment
Я думаю, он имеет в виду, что memcopy при чтении из сокета не является асинхронным, следовательно, epoll не полностью асинхронный. iocp позволяет вам указать буфер, в котором вы хотите хранить данные, когда вы запускаете асинхронный режим. операция, которую нельзя сделать с epoll. - person Arvid; 09.01.2012