Асинхронный дизайн цикла событий и проблемы

Я разрабатываю цикл событий для асинхронного сокета IO, использующий epoll/devpoll/kqueue/poll/select (включая выбор окон).

У меня есть две опции выполнения, операции IO:

Неблокирование режима, опроса на EAGAIN

  1. Сокет набора к не блокирующемуся режиму.
  2. Чтение-запись для снабжения сокетом.
  3. Если операция успешно выполняется, уведомление о завершении сообщения циклу событий.
  4. Если я получаю EAGAIN, добавьте сокет к "списку выборки" и опросите сокет.

Режим Polling: опросите и затем выполнитесь

  1. Добавьте сокет к списку выборки и опросите его.
  2. Ожидайте уведомления, что это читаемо перезаписываемый
  3. чтение-запись
  4. Уведомление о завершении сообщения циклу событий успешно выполняется

Мне это похоже, сначала потребовал бы меньшего количества системных вызовов при использовании в нормальном режиме, специально для записи в сокет (буферы являются довольно большими). Также похоже, что было бы возможно уменьшить издержки по количеству "избранного" выполнения, особенно хорошо, когда у Вас нет чего-то, что масштабируется хорошо как epoll/devpoll/kqueue.

Вопросы:

  • Есть ли какие-либо преимущества второго подхода?
  • Есть ли любые проблемы мобильности с неблокирующимися операциями на сокетах/дескрипторах файлов по многочисленным операционным системам: Linux, FreeBSD, Солярис, MacOSX, Windows.

Примечания: Не предлагайте использовать существующие event-loop/socket-api реализации

5
задан Artyom 6 May 2010 в 09:47
поделиться

3 ответа

Я не уверен, что есть кроссплатформенная проблема; в лучшем случае вам придется использовать Windows Sockets API, но с теми же результатами.

В противном случае кажется, что вы проводите опрос в любом случае (избегая ожидания блокировки), поэтому оба подхода подходят. Пока вы не ставите себя в положение для блокировки (например, чтение, когда нет данных, запись, когда буфер заполнен), это не имеет никакого значения.

Может быть, проще написать код / ​​понять первый подход; так что давай с этим.

Возможно, вам будет интересно ознакомиться с документацией по libev и c10k , где вы найдете интересные идеи / подходы по этой теме.

3
ответ дан 14 December 2019 в 13:29
поделиться

Первая конструкция - это Proactor Pattern, вторая - Reactor Pattern

Одно из преимуществ реакторного паттерна заключается в том, что вы можете спроектировать свой API таким образом, что вам не придется выделять буферы для чтения до тех пор, пока данные действительно не будут считаны. Это уменьшает расход памяти при ожидании ввода-вывода.

2
ответ дан 14 December 2019 в 13:29
поделиться

из моего опыта работы с сокетными приложениями с низкой задержкой:

для записи - старайтесь писать прямо в сокет из потока записи (для этого вам нужно получить мьютекс цикла событий), если запись не завершена, подпишитесь на готовность к записи с помощью цикла событий (select/waitformultipleobjects) и пишите из потока цикла событий, когда сокет становится доступным для записи

для чтения - будьте всегда "подписаны" на готовность ко всем сокетам, так что вы всегда читаете из потока цикла событий, когда сокет становится доступным для чтения

.
1
ответ дан 14 December 2019 в 13:29
поделиться