Я хочу написать простую многопользовательскую игру как часть моего проекта C ++.
Я подумал, так как я на это, я хотел бы сделать это должным образом, в отличие от просто сделать это.
Если я правильно понял: Apache использует архитектуру Thread-per-connection, а nginx использует цикл обработки событий, а затем выделяет рабочего [Икс] для входящего соединения. Я думаю, что nginx мудрее, так как поддерживает более высокий уровень параллелизма. Правильно?
Я тоже сталкивался с этим умная аналогия, но я не уверен, что это можно применить к моей ситуации. Аналогия также, кажется, очень идеалист. Я редко видел, чтобы мой компьютер работал на 100% процессоре (даже с открытыми вкладками Chrome Chrome, Photoshop и что-то не работает одновременно)
Кроме того, я натолкнулся на SO сообщение (каким-то образом оно исчезло из моей истории), где пользователь спросил, сколько потоков ему следует использовать, и один из ответов был таков: вполне приемлемо иметь около 700, даже до 10000 потоков. Этот вопрос был связан с JVM, хотя.
Итак, давайте оценим вымышленную базу пользователей примерно в 5000 пользователей. Какой подход должен быть «наиболее параллельным»?
Я допускаю, что вариант 2 звучит как лучшее решение для меня, но я очень зеленый во всем этом, поэтому я мог бы быть немного наивным и упустить какой-то очевидный недостаток. Кроме того, похоже, что это может быть довольно сложно реализовать.
PS: я рассматриваю возможность использования POCO C ++ Библиотеки. Предлагая любые альтернативные библиотеки (например, увеличение) хорошо со мной. Однако многие говорят, что библиотека POCO очень чистая и понятная. Итак, я бы предпочел использовать это, чтобы я мог узнать о какиз того, что я использую.
Реактивные приложения, конечно, лучше масштабируются, когда они написаны правильно. Это означает
Задачи в реактивных приложениях планируются приложением, а не операционной системой, поэтому они могут быть быстрее и использовать меньше памяти. Когда вы пишете приложение Reactive, вы говорите, что вы знаете проблемный домен настолько хорошо, что вы можете организовывать и планировать этот тип работы лучше, чем операционная система может планировать потоки, выполняющие ту же работу блокирующим образом.
Я большой поклонник реактивных архитектур, но они идут с затратами. Я не уверен, что написал бы свое первое приложение на c ++ как реактивное, обычно я стараюсь изучать одну вещь за раз.
Если вы решите использовать реактивную архитектуру, используйте хорошую среду, которая поможет вам спроектировать и структурировать ваш код, или вы получите спагетти. Что нужно искать:
Я не могу рекомендовать для этого библиотеку C ++, сейчас я занимаюсь разработкой серверов в Scala а также Akka которые обеспечивают все это отличной библиотекой компонованных фьючерсов для поддержания чистоты кода.
Желаем удачи в изучении C ++ и с каким выбором вы когда-либо делали.
Вариант 2 будет наиболее эффективно занимать ваше оборудование. Вот классическая статья, десять лет, но все еще хорошая.
http://www.kegel.com/c10k.html
Лучшая комбинация библиотек на сегодняшний день для структурирования приложений с параллелизмом и асинхронным ожиданием — это Boost Thread и Boost ASIO. Вы также можете попробовать C ++ 11 std thread
библиотека и std mutex
(но Boost ASIO во многих случаях лучше, чем мьютексы, просто всегда вызывайте один и тот же поток, и вам не нужны защищенные области). Держись подальше от std future
потому что он сломан:
http://bartoszmilewski.com/2009/03/03/broken-promises-c0x-futures/
Оптимальное количество потоков в пуле потоков — один поток на ядро процессора. 8 ядер -> 8 потоков. Плюс, может быть, несколько лишних, если вы считаете, что ваши потоки потоков могут иногда вызывать блокирующие операции.
FWIW, Poco поддерживает вариант 2 (ParallelReactor) с версии 1.5.1
Я думаю, что вариант 2 является лучшим. Что касается настройки размера пула, я думаю, что пул должен быть адаптивным. Он должен иметь возможность порождать больше потоков (с некоторым жестким ограничением) и удалять чрезмерные потоки во время низкой активности.
как можно предположить по аналогии (и это комментарии). это несколько зависит от приложения. Теперь, что вы строите здесь, это игровой сервер. давайте проанализируем это.
игровые серверы (как правило) выполняют много операций ввода-вывода и сравнительно мало вычислений, поэтому они далеки от 100% процессорных приложений.
с другой стороны, они также обычно меняют значения в некоторой базе данных (модель «игрового мира»). все игроки создают чтение и запись в эту базу данных. которая является точно проблемой пересечения в аналогии.
поэтому, хотя вы можете получить некоторую выгоду от обработки ввода-вывода в отдельных потоках, вы также потеряете от того, что отдельные потоки обращаются к одной и той же базе данных и ожидают ее блокировки.
поэтому вариант 1 или 2 приемлем в вашей ситуации. по причинам масштабируемости я бы не рекомендовал вариант 3.