Лучший подход к неблокирующему серверу / сокету прослушивания в многопоточном приложении в Windows? - PullRequest
2 голосов
/ 01 мая 2011

Я пишу TCP-сервер / клиентское приложение для Windows, чтобы познакомиться с Winsock API. Я пришел из UNIX и хотел бы знать, какой из них может быть лучшим подходом для реализации приложения:

Первая спецификация

  • Должен хорошо масштабироваться в многопроцессорных и однопроцессорных системах.
  • Нет жесткого ограничения на количество подключений.
  • Приложение может как прослушивать соединения, выступая в роли сервера, так и действовать как клиент.
  • Многопоточный.

Первый подход :

  • Неблокирующая селектоподобная розетка для прослушивания в потоке 'server'.
  • для каждого подключающегося клиента мы создаем отдельный поток.

Второй подход :

  • Блокировка сокета для прослушивания в потоке 'server'.
  • для каждого подключенного клиента мы создаем отдельный поток.

Третий подход :

  • Неблокирующая селектоподобная розетка для прослушивания в потоке 'server'.
  • Нет отдельного потока для каждого входящего соединения, протокол, я полагаю, должен хранить информацию о состоянии между сеансами.

Интересно, каков наиболее эффективный и масштабируемый подход, особенно если он может работать и с сокетом UDP.

Примечание: я пишу приложение на простом и старом языках C. Никакие .NET и C ++ не задействованы, исключения C ++ также отключены.

Ответы [ 3 ]

2 голосов
/ 02 мая 2011

Как говорит Гэри, порты завершения ввода / вывода являются наиболее эффективным способом управления несколькими сетевыми подключениями неблокирующим / асинхронным способом на платформах Windows.

С IOCP вы получаете уведомление о завершении сетевых операцийи вы можете обработать эти завершения с небольшим количеством потоков.Вы сами решаете, сколько потоков выделите для обработки завершений, а ядро ​​решает, когда использовать потоки, которые вы предоставляете.Он использует их в порядке LIFO, чтобы уменьшить переключение контекста, так что если вы используете только минимальное количество потоков, необходимое в любой точке, и вы повторно используете те же потоки, а не циклически перебираете все потоки, которые у вас есть дляuse.

Асинхронный характер программирования IOCP может показаться немного запутанным, но как только вы его освоите, он довольно прост.

У меня есть бесплатный серверный код IOCP, которыйдемонстрирует основы и предоставляет несколько примеров серверов, на которых довольно легко построить.Вы можете найти код здесь: http://www.serverframework.com/products---the-free-framework.html. Эта страница также ссылается на некоторые статьи, которые я написал, чтобы объяснить код.

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

0 голосов
/ 01 мая 2011

В Windows наилучшие характеристики достигаются при использовании вызовов завершения ввода / вывода.

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

К сожалению, вызовы завершения ввода-вывода Windows должны распределять много потоков для масштабирования, и это быстро убивает производительность (по сравнению с Linux epoll, который можетмасштабируется независимо от количества рабочих потоков , которое вы решаете задействовать в задаче).

Недавно я обнаружил http://gwan.com/ веб-сервер, который пришел из Windows и был портированпод линуксом.А их авторы подробно описывают проблему на своем форуме.

0 голосов
/ 01 мая 2011

Я написал асинхронный клиент, который не использует блокирующие сокеты, поэтому, если вам интересен этот подход, взгляните на мой клиент: http://codesprout.blogspot.com/2011/04/asynchronous-http-client.html

Это HTTP-клиент, но я показал очень мало обработки протокола HTTP, это всего лишь сокеты .NET. Сервер будет работать аналогичным образом: вы можете воспользоваться такими * асинхронными методами, как AsseptAsync.

...