2014-09-24 5 views
0

Позвольте мне указать на это, сказав, что я никогда не использовал порты завершения ввода-вывода, хотя я слышал о них уже много лет. Мой фон в основном связан с select, poll, epoll и WSAEventSelect в сочетании с WaitForMulitpleObjects. Пожалуйста, исправьте меня, если у меня возникло фундаментальное непонимание портов завершения ввода-вывода в следующем тексте.Порт ввода-вывода ввода-вывода для мелкомасштабных однопоточных приложений?

В рамках проекта на работе мне поручено разработать плагин (DLL) для моделирования, который позволяет клиенту подключаться к плагину и отправлять/получать данные в/из моделирования по TCP. Плагин действует как сервер. Моделирование имитирует каналы связи другого (не Ethernet) интерфейса, и имеет смысл иметь один сокет на канал в этом конкретном приложении. Я не знаю, сколько клиентов будет, или сколько каналов (сокетов) будет открыто каждым клиентом. Тем не менее, я знаю, что вполне возможно, что будет больше 64, и что это будет не очень большое количество, вероятно, не более тысячи.

Важным аспектом моделирования является то, что плагин разрешен только для работы, когда его функция test_cycle называется. Во время каждого цикла испытаний, мне нужно:

  1. принимать новые подключения клиентов
  2. Получение данных из гнезд и направить его к моделированию
  3. получающих данные из моделирования и направить его клиенту

Поскольку может быть больше, чем 64 гнезда, я не могу (легко) использовать WSAEventSelect и WSAWaitForMultipleEvents, чтобы проверить, если сокет может быть считан из, или если клиент корректно завершается соединение.

Так что я подумал о двух других способах, которыми я мог бы это сделать.

  1. Имейте каждое гнездо неблокирующее. Каждый раз, когда вызывается test_cycle, пропустите все сокеты, пытаясь получить до максимального количества данных на сокет.

  2. Используйте порт завершения ввода-вывода и выдайте асинхронный прием из сокетов. В test_cycle повторно наберите GetQueuedCompletionStatus с параметром dwMilliseconds, установленным на 0, пока не будет указан таймаут (WAIT_TIMEOUT?). Если происходит прием, отложите следующий принимающий вызов до окончания тестового цикла, чтобы клиент, спам сервера с сообщениями, не заставил нас зацикливаться на неопределенный срок в test_cycle (надеюсь).

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

Значит, для этой шкалы применения менее 1000 сокетов максимум и, как правило, менее 100, есть ли реальная польза от дополнительной сложности использования портов ввода-вывода ввода-вывода?

+0

Когда вы не достигните скорости и пропускной способности, возьмите ICOP. Хорошее описание здесь http://stackoverflow.com/questions/754068/win32-overlapped-io-completion-routines-or-waitformultipleobjects/755135#755135 – user743414

+0

Я решил, что для первой версии этого плагина это будет быстрее выполнять только опрос сокетов один раз за итерацию 'test_cycle'. Затем код можно профилировать в отношении реальных сценариев и переписать для использования IOCP, если это необходимо. Я предпочел бы получить рабочую первую версию, чем заставить людей ждать дольше для версии IOCP, которая может быть даже не намного быстрее. –

ответ

0

Я думаю, вы могли бы это сделать:
1) Постройте поток слушателя.Для каждого соединения отправляется копия сокета в пул потоков;
2) Создайте пул потоков для обработки запросов;

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

Положите контрольные лимиты, чтобы ресурсы не были исчерпаны.