Позвольте мне указать на это, сказав, что я никогда не использовал порты завершения ввода-вывода, хотя я слышал о них уже много лет. Мой фон в основном связан с select
, poll
, epoll
и WSAEventSelect
в сочетании с WaitForMulitpleObjects
. Пожалуйста, исправьте меня, если у меня возникло фундаментальное непонимание портов завершения ввода-вывода в следующем тексте.Порт ввода-вывода ввода-вывода для мелкомасштабных однопоточных приложений?
В рамках проекта на работе мне поручено разработать плагин (DLL) для моделирования, который позволяет клиенту подключаться к плагину и отправлять/получать данные в/из моделирования по TCP. Плагин действует как сервер. Моделирование имитирует каналы связи другого (не Ethernet) интерфейса, и имеет смысл иметь один сокет на канал в этом конкретном приложении. Я не знаю, сколько клиентов будет, или сколько каналов (сокетов) будет открыто каждым клиентом. Тем не менее, я знаю, что вполне возможно, что будет больше 64, и что это будет не очень большое количество, вероятно, не более тысячи.
Важным аспектом моделирования является то, что плагин разрешен только для работы, когда его функция test_cycle
называется. Во время каждого цикла испытаний, мне нужно:
- принимать новые подключения клиентов
- Получение данных из гнезд и направить его к моделированию
- получающих данные из моделирования и направить его клиенту
Поскольку может быть больше, чем 64 гнезда, я не могу (легко) использовать WSAEventSelect
и WSAWaitForMultipleEvents
, чтобы проверить, если сокет может быть считан из, или если клиент корректно завершается соединение.
Так что я подумал о двух других способах, которыми я мог бы это сделать.
Имейте каждое гнездо неблокирующее. Каждый раз, когда вызывается
test_cycle
, пропустите все сокеты, пытаясь получить до максимального количества данных на сокет.Используйте порт завершения ввода-вывода и выдайте асинхронный прием из сокетов. В
test_cycle
повторно наберитеGetQueuedCompletionStatus
с параметромdwMilliseconds
, установленным на0
, пока не будет указан таймаут (WAIT_TIMEOUT
?). Если происходит прием, отложите следующий принимающий вызов до окончания тестового цикла, чтобы клиент, спам сервера с сообщениями, не заставил нас зацикливаться на неопределенный срок вtest_cycle
(надеюсь).
интерфейс к моделированию не поточно-, и есть очень мало обработки работы, чтобы сделать для пересылки данных для моделирования, так что я не думаю, что будет какой-либо польза от рабочих потоков для порта завершения ввода-вывода, который просто сделает блокировку и вызовет API моделирования. Однако отсутствие необходимости опроса каждого сокета может привести к повышению производительности.
Значит, для этой шкалы применения менее 1000 сокетов максимум и, как правило, менее 100, есть ли реальная польза от дополнительной сложности использования портов ввода-вывода ввода-вывода?
Когда вы не достигните скорости и пропускной способности, возьмите ICOP. Хорошее описание здесь http://stackoverflow.com/questions/754068/win32-overlapped-io-completion-routines-or-waitformultipleobjects/755135#755135 – user743414
Я решил, что для первой версии этого плагина это будет быстрее выполнять только опрос сокетов один раз за итерацию 'test_cycle'. Затем код можно профилировать в отношении реальных сценариев и переписать для использования IOCP, если это необходимо. Я предпочел бы получить рабочую первую версию, чем заставить людей ждать дольше для версии IOCP, которая может быть даже не намного быстрее. –