Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Асинхронный поточный tcp-сервер

Автор вопроса: mark_djОтветов: 4

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

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

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

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

tcpactionscript-3amf

Ответы

Ответ 1 · рейтинг 4 · Kennet Belenky

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

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

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

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

Ответ 2 · рейтинг 3 · Timores

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

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

Ответ 3 · рейтинг 1 · Byron Whitlock

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

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

Ответ 4 · рейтинг 1 · Marcelo Cantos

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы