Асинхронный многопоточный tcp сервер - PullRequest
3 голосов
/ 31 марта 2010

Я хочу создать высокопроизводительный сервер на C #, который может занять около 10 тыс. Клиентов. Теперь я начал писать TcpServer с C # и для каждого клиентского соединения я открываю новый поток. Я также использую один поток, чтобы принять соединения. Пока все хорошо, отлично работает.

Сервер должен десериализовать входящие объекты AMF, выполнить некоторую логику (например, сохранение позиции игрока) и отправить некоторый объект обратно (сериализация объектов). Я не беспокоюсь о сериализации / десериализации части atm.

Моя главная проблема в том, что у меня будет много потоков с клиентами 10k, и я где-то читал, что ОС может содержать только несколько потоков.

Есть ли какие-либо источники / статьи, доступные при написании приличного асинхронного многопоточного сервера? Есть ли другие возможности, или 10k потоков будут работать нормально? Я посмотрел в Google, но я не смог найти много информации о шаблонах дизайна или способах, которые объясняют это ясно

Ответы [ 4 ]

4 голосов
/ 31 марта 2010

Вы столкнетесь с рядом проблем.

  1. Вы не можете раскрутить 10000 потоков по нескольким причинам. Это погубит планировщик ядра. Если вы используете 32-разрядную версию, то адресное пространство стека по умолчанию, равное 1 МБ, означает, что потоки 10 КБ резервируют около 10 ГБ адресного пространства. Это не удастся.

  2. Вы также не можете использовать простую систему выбора. В его основе выберите O (N) для количества сокетов. С розетками 10К это плохо.

  3. Вы можете использовать порты завершения ввода-вывода. Это сценарий, для которого они предназначены. Насколько мне известно, нет стабильной, управляемой библиотеки портов завершения ввода-вывода. Вам придется написать свой собственный, используя P / Invoke или Managed C ++. Веселитесь.

3 голосов
/ 31 марта 2010

Способ написания эффективного многопоточного сервера - использовать порты завершения ввода / вывода (использование потока на запрос довольно неэффективно, как упоминает @Marcelo)

Если вы используете асинхронную версию класса сокетов .NET, вы получите это бесплатно. См. этот вопрос , в котором есть ссылки на документацию.

1 голос
/ 31 марта 2010

Вы хотите изучить использование портов завершения ввода-вывода . В основном у вас есть пул потоков и очередь операций ввода-вывода.

Порты завершения ввода / вывода обеспечивают эффективная модель потоков обработка нескольких асинхронных операций ввода-вывода запросы на многопроцессорной системе. Когда процесс создает ввод / вывод порт завершения, система создает связанный объект очереди для запросов чья единственная цель заключается в обслуживании этих Запросы. Процессы, которые обрабатывают многие параллельные асинхронные запросы ввода / вывода может сделать это быстрее и эффективнее используя порты завершения ввода / вывода в Совместно с заранее выделенным пул потоков, чем путем создания потоков в то время, когда они получают ввод / вывод запрос.

1 голос
/ 31 марта 2010

Вы определенно не хотите поток за запрос. Даже если у вас меньше клиентов, накладные расходы на создание и уничтожение потоков приведут к повреждению сервера, и вы никак не сможете получить до 10 000 потоков; планировщик ОС умрет ужасной смертью задолго до этого.

В Интернете есть множество статей об асинхронном программировании сервера на C # (например, здесь ). Просто погуглите немного.

...