Порт завершения ввода / вывода для небольших однопоточных приложений?

Позвольте мне добавить префикс, сказав, что я никогда не использовал порты завершения ввода / вывода, хотя слышал о них уже много лет. Мой фон в первую очередь с 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

Решение

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

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

Установите контрольные пределы, чтобы гарантировать, что ресурсы не истощаются.

0

Другие решения


По вопросам рекламы [email protected]