Синхронизация потоков на сервере C ++ - PullRequest
0 голосов
/ 09 июня 2018

Я провел несколько дней в сети, чтобы найти ответ на то, что написано в заголовке, но нашел только решения, которые не относятся к моей проблеме (примеры: мьютекс, алгоритмы блокировки и некоторые неблокирующие) ...

Моя проблема:

Я создаю многопользовательскую видеоигру, которую я буду использовать для моего последнего экзамена в старшей школе, используя c ++ и SFML, но я действительно не могу найти способ синхронизациивсе мои темы.В настоящее время моя программа работает с «большим» игровым потоком, потоком, который в каждом цикле обновляет все переменные, такие как позиции игрока, маркеры и т. Д., И по одному потоку на клиента, которые обрабатывают ввод / вывод tcp-сокета с помощью SFML (я мог бы это сделатьсо стандартными сокетами, но они мне нравятся), и каждый клиентский поток должен прочитать текущее состояние игры, чтобы отправить данные игроку.

Но если игровой поток изменяет данные, пока одинклиентского потока читает его, это, очевидно, приводит к ошибке сегментации.
С количеством клиентов X (по сути, моя цель - обработать все возможные клиенты, ограниченные мощностью моей машины, поэтому их может быть как 10, так и 1000).), как я могу синхронизировать все их потоки с игровым потоком?

Если я использую мьютекс или другие алгоритмы блокировки, нет необходимости использовать больше потоков, чем один.В конце игрового цикла я мог просто отправлять и получать данные от всех клиентов.Но это замедляет все, намного больше, чем многопоточная система.Один клиент с медленным соединением может замедлить все.

Что я могу сделать?Один большой поток всегда активен, изменяя все, что не должно быть остановлено, и сотни других маленьких потоков, которые должны читать данные больших потоков в реальном времени.

В любом случае, спасибо!

Если я каким-то образомпропустил цепочку вопросов, которая объясняла это, пожалуйста, сошлитесь на меня.

(Ps. Единственное, что я использую с SFML - это графическая система, примеры с winsock / linux также хороши. IЯ использую потоки c ++ 11)

Извините за мой английский: c Я приложил все усилия ...

Редактировать: использовал html br's, чтобы закончить строку: P ввод ключа не делает 'т работа

1 Ответ

0 голосов
/ 10 июня 2018

Часть искусства написания многопоточных программ - это научиться структурировать программу, чтобы минимизировать потребность в синхронизации.Один пример:

Ваша «ветка большой игры» (BGT) постоянно обновляет состояние игры.Не позволяйте клиентским потокам когда-либо видеть это состояние.Вместо этого, в конце каждого цикла BGT должен делать доступную только для чтения копию состояния игры.Затем пусть клиентские потоки посмотрят на самую новую копию.

Клиентам все равно придется заблокировать и разблокировать некоторый мьютекс, чтобы получить shared_ptr для самой последней копии, а также может быть некоторая блокировка/ разблокировка в механизме shared_ptr, когда каждый клиент заканчивает просмотр копии, но общее время, в течение которого любой клиент будет удерживать любой мьютекс заблокированным, будет на намного меньше, чем если бы каждый клиент сохранял всю игрусостояние заблокировано при отправке по сети.

Многопоточные приложения часто выполняют больше операций копирования, чем непоточные, но это окупается.В этом случае BGT платит цену за создание полной копии игрового состояния в каждом цикле.Но выгода в том, что все клиентские потоки могут одновременно обращаться к этой копии только для чтения, в то время как BGT одновременно вычисляет следующий снимок состояния игры.

...