【问题标题】:Optimizing a LAN server for a game为游戏优化 LAN 服务器
【发布时间】:2010-12-16 10:01:00
【问题描述】:

我是一个学校游戏项目的网络程序员。我们希望在 LAN 上同时拥有多达 16 名玩家。我正在使用服务器-客户端模型,并且正在为每个加入的客户端创建一个新线程。但是,如果非阻塞端口从客户端接收到任何信息,则仅检查每个线程就浪费了大量 CPU 时间。

我一直在阅读 Anthony Johns 和 Jim Ohlund 的“Microsoft Windows 网络编程”。他们提到了服务器-客户端应用程序的两种不同模型。

1.)

  • 使用重叠的 IO 套接字选项
  • 将重叠的结构和 WorkerRoutine 传递给 WSARecv
  • 调用 WSAWaitForMultipleEvents() 或 SleepEX() 将线程设置为可警报。
  • 在 WorkerRoutines 中处理接收到的数据。

2.)

  • 使用重叠的 IO 套接字选项
  • 创建 Io 完成端口
  • 创建 ServerWorkerThreads(不管你有多少个 CUP)
  • 将完成端口与套接字关联。
  • 在ServerWorkerThread中调用GetQueuedCompletionStatus,处理接收到的数据。

我想知道哪种方法最适合我的情况。这本书说完成端口模型非常适合成千上万的客户,但这让我认为它是为大型服务器而不是小型局域网游戏而设计的。 WorkerRoutines/Event 系统似乎更简单。

【问题讨论】:

  • 贴出你觉得浪费时间的代码,也许有人可以提出更优化的解决方案。否则,这里就没有真正的编程问题。
  • 你读过 C10K 问题吗?它与您的一些问题有关。 kegel.com/c10k.html

标签: c++ c optimization networking network-programming


【解决方案1】:

您应该停止使用非阻塞端口。它们对并发性非常有用,而且你有线程。

只需让团队中的每个线程在端口上等待,当它解除阻塞时,它就会有一些事情要做,这样你就不会浪费时间在旋转。如果您有其他事情要做(例如更新游戏状态),请使用其他根本不执行任何网络 I/O 的线程来完成。

并确保使用同步原语(信号量)来避免与自己不同步。

这是实现它的超级多线程方式,您可能应该使用它。另一种方法是有一个锁步推进状态机来更新所有客户端循环。如果您想通过 Internet 玩游戏,这将毫无用处,因为不同的 ping 将使您的游戏以不同的速度运行。

【讨论】:

  • 那么当我的端口阻塞时,它会浪费 CPU 周期还是休眠?
  • 阻塞的线程进入休眠状态直到数据到达。
猜你喜欢
  • 2013-11-12
  • 2011-12-03
  • 2011-09-04
  • 2012-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
相关资源
最近更新 更多