Асинхронный дизайн и проблемы цикла событий - PullRequest
5 голосов
/ 06 мая 2010

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

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

Неблокирующий режим, опрос по EAGAIN

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

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

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

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

Вопросы:

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

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

Ответы [ 3 ]

3 голосов
/ 06 мая 2010

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

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

Возможно, первый подход легче кодировать / понимать; итак, иди с этим.

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

2 голосов
/ 10 мая 2010

Первый дизайн - это Схема реактора , второй - Шаблон реактора

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

1 голос
/ 10 мая 2010

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

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

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

...