2010-03-30 2 views
3

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

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

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

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

ответ

4

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

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

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

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

+0

Пока я согласен, потоки 10k - это не путь. 32-битные окна могут легко создавать потоки 10k. http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx –

+0

«Базовый стек ядра составляет 12 КБ на 32-битной Windows и 24 КБ на 64-битной Windows. 14,225 потоков требуют около 170 МБ резидентная доступная память ", http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx –

+0

Да, удача управляется потоком с нулевым стеком. –

1

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

В C# имеется множество статей о программировании асинхронного сервера (например, here). Просто google немного.

+1

10k threads * 1kb stackspace = 10meg, not 10gig. Очевидно, что вы будете округлены до детализации страницы, хотя и в действительности, а не только, но dwAllocationGranularity (64kb). Тем не менее, потоки 10k с минимальным количеством стеков составляют ~ 625meg, а не 10gig :) (это исключает непрофессиональные накладные расходы, хотя) – snemarch

+0

+1 @snemarch. Должно быть, было поздно. Я удалил комментарии к размеру стека. –

1

Вы хотите изучить IO completion ports. У вас в основном есть threadpool и очередь операций ввода-вывода.

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

3

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

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