Я разрабатываю цикл событий для асинхронного сокета IO, использующий epoll/devpoll/kqueue/poll/select (включая выбор окон).
У меня есть две опции выполнения, операции IO:
Неблокирование режима, опроса на EAGAIN
Режим Polling: опросите и затем выполнитесь
Мне это похоже, сначала потребовал бы меньшего количества системных вызовов при использовании в нормальном режиме, специально для записи в сокет (буферы являются довольно большими). Также похоже, что было бы возможно уменьшить издержки по количеству "избранного" выполнения, особенно хорошо, когда у Вас нет чего-то, что масштабируется хорошо как epoll/devpoll/kqueue.
Вопросы:
Примечания: Не предлагайте использовать существующие event-loop/socket-api реализации
Я не уверен, что есть кроссплатформенная проблема; в лучшем случае вам придется использовать Windows Sockets API, но с теми же результатами.
В противном случае кажется, что вы проводите опрос в любом случае (избегая ожидания блокировки), поэтому оба подхода подходят. Пока вы не ставите себя в положение для блокировки (например, чтение, когда нет данных, запись, когда буфер заполнен), это не имеет никакого значения.
Может быть, проще написать код / понять первый подход; так что давай с этим.
Возможно, вам будет интересно ознакомиться с документацией по libev и c10k , где вы найдете интересные идеи / подходы по этой теме.
Первая конструкция - это Proactor Pattern, вторая - Reactor Pattern
Одно из преимуществ реакторного паттерна заключается в том, что вы можете спроектировать свой API таким образом, что вам не придется выделять буферы для чтения до тех пор, пока данные действительно не будут считаны. Это уменьшает расход памяти при ожидании ввода-вывода.
из моего опыта работы с сокетными приложениями с низкой задержкой:
для записи - старайтесь писать прямо в сокет из потока записи (для этого вам нужно получить мьютекс цикла событий), если запись не завершена, подпишитесь на готовность к записи с помощью цикла событий (select/waitformultipleobjects) и пишите из потока цикла событий, когда сокет становится доступным для записи
для чтения - будьте всегда "подписаны" на готовность ко всем сокетам, так что вы всегда читаете из потока цикла событий, когда сокет становится доступным для чтения
.