В качестве побочного проекта я в настоящее время пишу сервер для вековой игры, которую я играл. Я пытаюсь сделать сервер как можно более гибким, но мне интересно, что будет хорошим дизайнерским решением для многопоточности. В настоящее время у меня есть следующая последовательность действий:
- Запуск (создает) →
- Сервер (прослушивает для клиентов, создает) →
- Клиент (прослушивает команды и отправляет данные периода)
Я предполагаю, что в среднем 100 клиентов, так как это был максимум в любой момент времени для игры. Каким было бы правильное решение, как для нарезки всего этого? Моя текущая настройка выглядит следующим образом:
- 1 поток на сервере, который прослушивает новые подключения, в новом соединении создает клиентский объект и начинает прослушивание снова.
- Клиентский объект имеет один поток, прослушивает входящие команды и отправляет периодические данные. Это делается с использованием неблокирующего сокета, поэтому он просто проверяет, доступны ли данные, об этом и затем отправляет сообщения, которые он поставил в очередь. Вход выполняется до начала цикла отправки-получения.
- Один поток (на данный момент) для самой игры, поскольку я считаю, что это отдельно от всей клиент-серверной части, архитектурно говоря.
Это приведет к тому, что в общей сложности будет 102 потока. Я даже рассматриваю возможность предоставления клиенту 2 потока, один для отправки и один для получения. Если я это сделаю, я могу использовать блокирующий ввод-вывод в потоке получателя, что означает, что поток будет в основном бездействовать в средней ситуации.
Моя главная проблема заключается в том, что, используя эти много нитей, я буду использовать ресурсы. Я не беспокоюсь о гоночных условиях или тупиках, так как мне все равно придется иметь дело.
Мой дизайн настроен таким образом, что я мог использовать один поток для всех клиентских коммуникаций, независимо от того, 1 или 100. Я отделил логику связи от самого объекта клиента, поэтому я мог бы реализовать его, не переписывая много кода.
Основной вопрос: неправильно ли использовать более 200 потоков в приложении? Имеет ли он преимущества? Я собираюсь запустить это на многоядерной машине, будет ли это иметь много преимуществ в таких ядрах?
Спасибо!
Из всех этих потоков большинство из них будут заблокированы обычно. Я не ожидаю, что соединения будут более 5 в минуту. Команды от клиента появятся нечасто, я бы сказал, что в среднем 20 в минуту.
Идя по ответам, которые я получаю здесь (переключение контекста было хитом производительности, о котором я думал, но я не знал этого, пока вы не отметили это, спасибо!) Я думаю, что я пойду за подход с одним слушатель, один приемник, один отправитель и некоторые другие вещи; -)