作为一个副项目,我目前正在为我曾经玩过的一个古老的游戏编写服务器。我试图使服务器尽可能松耦合,但我想知道多线程的一个好的设计决策是什么。目前,我有以下一系列操作:
- 启动(创建)->
- 服务器(监听客户端,创建)->
- 客户端(监听命令并发送周期数据)
我假设平均有 100 个客户,因为这是游戏在任何给定时间的最大值。对于整个事情的线程化,正确的决定是什么?我目前的设置如下:
- 服务器上的 1 个线程侦听新连接,在新连接上创建一个客户端对象并再次开始侦听。
- 客户端对象有一个线程,监听传入的命令并定期发送数据。这是使用非阻塞套接字完成的,因此它只是检查是否有可用数据,处理它,然后发送它已排队的消息。登录在发送-接收周期开始之前完成。
- 一个线程(目前)用于游戏本身,因为我认为从架构上讲,它与整个客户端-服务器部分是分开的。
这将导致总共 102 个线程。我什至正在考虑给客户端 2 个线程,一个用于发送,一个用于接收。如果我这样做,我可以在接收线程上使用阻塞 I/O,这意味着线程在一般情况下大部分是空闲的。
我主要担心的是,通过使用这么多线程,我将占用资源。我不担心比赛条件或死锁,因为无论如何我都必须处理这些事情。
我的设计是这样设置的,即我可以使用单个线程进行所有客户端通信,无论它是 1 还是 100。我已经将通信逻辑与客户端对象本身分离,因此我可以实现它而无需重写很多代码。
主要问题是:在应用程序中使用超过 200 个线程是错误的吗?它有优点吗?我正在考虑在多核机器上运行它,这样会充分利用多核吗?
谢谢!
在所有这些线程中,它们中的大多数通常会被阻塞。我预计连接数不会超过每分钟 5 个。来自客户端的命令很少会出现,我会说平均每分钟 20 个。
按照我在这里得到的答案(上下文切换是我正在考虑的性能影响,但在你指出之前我不知道,谢谢!)我想我会选择一个听众的方法,一个接收者、一个发送者和一些杂项;-)