【问题标题】:Thread synchronization on a C++ serverC++ 服务器上的线程同步
【发布时间】:2018-11-19 12:14:13
【问题描述】:

我已经上网几天来寻找标题上所写内容的答案,但只找到了不适用于我的问题的解决方案(例如互斥锁、锁定算法和一些非阻塞算法)。 .

我的问题是:

我正在使用 c++ 和 SFML 构建一个多人视频游戏,我将在高中的最后一次考试中使用它,但我真的找不到同步所有线程的方法。目前,我的程序使用一个“大”游戏线程,每个周期更新所有变量(如玩家的位置、子弹等)的线程和每个客户端一个线程,它使用 SFML 处理 tcp-socket I/O(我可以做到也使用标准套接字,但我喜欢它们),每个客户端线程都必须读取游戏的当前状态才能将数据发送给玩家。

但如果游戏线程正在修改数据,而其中一个客户端线程正在读取数据,这显然会导致分段错误。
有 X 个客户端(基本上,我的目标是处理所有可能受我机器功率限制的客户端,因此它们可以是 10 也可以是 1000),我怎样才能将它们的所有线程与游戏线程同步?

如果我使用互斥锁或其他阻塞算法,则无需使用多个线程。在游戏周期结束时,我可以让所有客户端发送和接收数据。但这会减慢一切,比多线程系统要慢得多。一个连接速度慢的客户端可能会减慢一切。

我能做什么?一个大线程总是主动修改所有不能停止的东西,而其他数百个小线程必须实时读取大线程数据。

还是谢谢!

如果我错过了解释这一点的问题线索,请将其链接给我。

(附注:我在 SFML 中使用的唯一重要的是图形系统,winsock/linux 的示例也很好。我使用的是 c++11 线程)

对不起我的英语:c 我已经尽力了......

编辑:使用 html br 结束行:P 输入键不起作用

【问题讨论】:

  • 不幸的是,对于这个网站来说,这个问题太宽泛了,但有几点需要注意。多个线程修改数据等不会“明显”导致段错误。那是完全不同的。通常结果是不一致的数据。至于同步,从客户端读取数据或将其发送给它们不会导致速度变慢,即使某些连接速度很慢。不要使用阻塞 IO,在某种程度上你没问题。如果看起来有问题,请断开太慢的连接。不需要每个客户端都有一个线程。
  • 每个客户端一个线程听起来很多。
  • 你的键盘有回车键吗?了解如何使用它。
  • 我用 enters :P 我不知道为什么消息被这样移动了。我现在会尝试修改它。
  • 你总是可以让你的服务器变成单线程的;然后所有的竞争条件、死锁和其他与多线程相关的问题都消失了。您可能需要使用非阻塞 I/O 来确保您的单线程不会在网络调用中被阻塞。

标签: c++ multithreading c++11 client-server sfml


【解决方案1】:

编写多线程程序的一部分艺术是学习构建程序以最小化对同步的需求。一个例子:

您的“大游戏线程”(BGT) 会不断更新游戏状态。不要让客户端线程永远看到该状态。相反,让 BGT 在每个循环结束时制作游戏状态的只读副本。然后,让客户端线程查看最新的副本。

客户端仍然需要锁定和解锁一些互斥体才能获得最新副本的shared_ptr,并且当每个客户端完成查看时,shared_ptr 机器中也可能会有一些锁定/解锁副本,但是任何客户端保持任何互斥锁锁定的总时间将比每个客户端在通过网络发送它时保持整个游戏状态锁定的情况。

多线程应用程序通常比非线程应用程序执行更多的复制,但它得到了回报。在这种情况下,BGT 会付出代价,在每个循环中制作完整的游戏状态副本。但回报是,客户端线程都可以同时访问该只读副本,而 BGT 同时计算下一个游戏状态快照。

【讨论】:

  • 这是我目前的解决方案。我创建了一个游戏状态列表,客户端线程只读取最新的。另一个线程删除所有未使用的状态。这会导致游戏大量过载,因为每个变量的权重都是正常变量的 x 倍。如果有 100 万个游戏状态(它发生了),一个位置的权重会增加 1000 倍。这听起来不太好。
  • "另一个线程删除了所有未使用的状态。"我不会为此使用单独的线程。我会这样写,以便每个快照都被最后一个需要它的线程删除。事实上,我根本不会编写“删除”代码,因为我会让std::make_shared<snapshot>(...)std::smart_ptr<snapshot> 处理它。
  • @Davide Re,“1000 个游戏状态 [快照]”您是说客户端线程可以落后一千帧吗?如果这是真的,我会寻找某种快速通道/捷径让客户赶上。 (例如,以降低的帧速率显示)。我对你的游戏是如何玩的一无所知,但降低帧率的显示可能比动作滞后半分钟的显示更具可玩性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多