线程是服务器的一种希有资源,它的创建,销毁,切换都需要很多服务器的其它资源。而在游戏服务
器中,只要没有在多线程之间有共享数据的操作,都是可以并发的,即可以是多线程操作的。
比如不同用户各自的操作处理,或同一个用户的数据更新到数据库的操作等等。那为了提高并发性,
是不是线程越多越好呢?多少才合适呢?先不说游戏服务器的特殊性,就按普通的服务器业务来说,
最合适的线程数是多少呢?说到线程,那一定是和cpu核数相关的。在其它的文章里面,我们可以看
到这样的结论:

一般说来,大家认为线程池的大小经验值应该这样设置:(其中N为CPU的个数)

如果是CPU密集型应用,则线程池大小设置为N+1
如果是IO密集型应用,则线程池大小设置为2N+1
但是,IO优化中,这样的估算公式可能更适合:
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )
CPU数目
因为很显然,线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。
*

下面举个例子:

比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU
核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32。这个公式进一步转化为:

最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目

综上所看,线程数并不是越多越好,而是要适量。比如如果游戏服务器是使用netty开发的,那么
boss线程一般1~2个就足够,而work线程可以根据服务器配置和上面的公式算出最合适的线程数。我们
知道,在netty的业务操作中,也就是Channel的Handlerr操作中,不应该有IO操作,因为IO操作时间
长,而所有的channel是共用work线程的,如果有IO操作,就会卡往其它的请求处理。所以一般来
说,游戏服务器中的数据应该提前加载到内存中,这样即可消除IO操作。

云服务 CPU 核数 线程 服务器cpu核数和线程数_云服务 CPU 核数 线程


那么问题来了,游戏服务器中不可能没有IO操作,比如登陆时数据库的查询,部分重要数据的即时更
新到数据库,或向其它服务发送http请求等等。这该怎么处理呢?其实我们发现,这些操作都是可以
并行的,他们之间没有依赖关系也没有共享数据,即没有什么顺序要求(当前同一个用户的对数据库
的操作应该是有序的,同一个用户的操作应该放到同一个单线程池中处理,当然多个用户可以共用这
个单线程池,使用netty的线程模型即可,EventExecutor)。所以我们可以把这些操作放到一个线程
池中。线程池的数量和每个线程池中的线程数我们可以很好的把控。这个可以封装到服务器的框架里
面。