OldJiang.com

浩毛的博客

OldJiang.com
posts - 14, comments - 81, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

多线程还是单线程?

Posted on 2010-07-06 00:06 浩毛 阅读(9166) 评论(13)  编辑 收藏 引用 所属分类: 服务器开发

一个典型的游戏服务器设计中,一般都是用的多线程,服务器中一般运行两类线程,N个SOCKET IO线程,1个逻辑线程,
IO线程接受客户端发来的信息,通过消息队列发送给逻辑线程处理后,再发送消息给客户端,发送消息这里一般是IO线程处理实际发送。

其实我认为,如果逻辑线程都是消耗的CPU运算资源的话,服务器完全采用单线程的方式来做。

首先,我们看IO处理,基本就是数据入队、出队,send、recv操作,作为服务器的SOCKET处理一般都是异步SOCKET,也就是说,send、recv操作只是将信息copy到socket底层的发送接收缓冲区去了,不存在IO堵塞的问题。

然后,我们再来看逻辑处理,前面已经说了,采用单线程的前提是逻辑处理只是消耗CPU运算资源,那么,不管你开几个线程,对单核的CPU来说,它的处理速度就是这么多,并不会因为你线程开的越多,就处理的越快。

因此我们可不可以这样说呢,在单核机器上,只消耗CPU运算的服务,多线程并不比单线程能提高多少效率。

接下来,我们再讨论下多核的情况,你肯定要想,我这台服务器是4个双核CPU,就只跑一个单线程的服务器不是亏死了,多线程多好,我开8个线程,就能很好的利用我的机器啦。是啊,我也觉得这样很好,不过在LINUX、UNIX下,对线程的支持并不像WINDOWS下那么好,LINUX、UNIX下一般都是用LWP(轻量级进程)的方式来支持多线程程序的,Linux内核只提供了轻量进程的支持,限制了更高效的线程模型的实现,但Linux着重优化了进程的调度开销,一定程度上也弥补了这一缺陷。同时,滥用多线程也会造成不必要的上下文切换,不必要的同步机制的引入(如pthread_mutex),让程序频繁的在内核和用户间频繁切换。另外,从开发角度来看,单线程开发比多线程环境开发更不容易出错和更加健壮。

在游戏服务器架构中,为了提高玩家在线人数,实现负载均衡,现在一般都是采用分布式的多进程服务器集群的方式,我们来看看服务器集群中,每个服务进程是采用多线程的方式还是单线程的方式好呢?我觉得,对于有慢速IO访问的需求的应用进程,多线程肯定比单线程好,最典型的情况就是数据库访问这块,完全可以采用N个DB线程,一个逻辑线程的架构,而对只是消耗CPU运算资源的应用进程,尽量单线程就行了,如果觉得单线程负载不行的话,完全可以分成多个进程来跑。。

以上只是我自己的一些看法,表达有限,欢迎指正。。。

Feedback

# re: 多线程还是单线程?  回复  更多评论   

2010-07-06 08:50 by tanxw
多进程单线程。
一个游戏逻辑进程,一个SOCKET进程,一个DB进程,对于MMORPG,还有一个NPC进程处理怪物的AI。

# re: 多线程还是单线程?  回复  更多评论   

2010-07-06 09:38 by 浩毛
NPC进程不一定要有的。

# re: 多线程还是单线程?  回复  更多评论   

2010-07-06 11:58 by Kevin Lynx
@tanxw
AI单独到一个进程里,这些逻辑模块之间又涉及到线程同步问题了。
@浩毛
对于只有游戏逻辑和网络IO的进程而言,你说的只开一个线程,似乎也在理。不过由于网络IO这块情况可能比理论上要复杂很多,例如实际使用的网络IO机制(IOCP)、网络层数据的拷贝、封包组建等,似乎保险的做法还是开多个线程来做。何况,逻辑线程可能还会涉及到限帧问题。拿去运营的服务器一般也是多核的。LINUX下线程实现的效率如果真的太那个啥,或者可以考虑多进程的结构(网络模块和逻辑模块位于不同进程)。

# re: 多线程还是单线程?  回复  更多评论   

2010-07-06 12:11 by 无名氏
写一个游戏要考虑的因素太多了

# re: 多线程还是单线程?  回复  更多评论   

2010-07-06 18:28 by zuhd
1,socket
2,db
3,event(这里的event是对网络包的切割或是拼接形成的一个完整事件)
很和谐的三层,在linux一个独立的服务器(功能独立),基本照这个模式可以复制出N个服务器。至于是否拆成独立进程,我是这么考虑的,
1,该模块是否有很独立,单一的功能,如验证
2,该模块的功能对性能要求是否苛刻,比如AI

# re: 多线程还是单线程?  回复  更多评论   

2010-07-06 20:39 by 欣萌
在你假设的条件下 有道理。

# re: 多线程还是单线程?  回复  更多评论   

2010-07-07 17:14 by 欣萌
我今天早上想了想 不一定对。

因为有小task 和 大task的区别。

# re: 多线程还是单线程?  回复  更多评论   

2010-07-07 17:50 by Vincent
一个DB服务器
一个logingate服务器
一个逻辑服务器


其实个人觉得有一个NPC服务器来处理各种模拟事件来维护一个真实的world挺好

# re: 多线程还是单线程?  回复  更多评论   

2010-07-08 18:07 by 浩毛
@Kevin Lynx

游戏服务器要提高负载,都是集群的方式,一般都有N个网关的,不管你用IOCP,EPOLL还是KQUEUE,甚至是SELECT都可以的,而网关的功能很简单的,就是外网和内网之间的信息转发。因此一个线程就够了。

对于游戏服务器组件之间的通讯(IPC)来说,就那么几个连接,SOCKET的上下文切换的消耗是很小的。

另外,IOCP,EPOLL,KQUEUE这种机制,只有在服务器接受了N个客户端,但是服务器只和其中的很少一部分客户端在交互的情况下(很少的客户端在并发接收和发送)才能体现出它们的优点。
而对于游戏服务器来说,你有1000个客户端在线,这些客户端基本都在同时发包,可读可写事件每个FD都差不多同时产生,这种情况下,EPOLL还是SELECT,效率上来看差别不大。因此,对于需要处理大量高并发的长连接请求的服务器来说,多进程的方式要轻松的多。

# re: 多线程还是单线程?  回复  更多评论   

2010-07-09 14:42 by 金庆
两者性能没什么差别,就看哪个实现简单了。

# re: 多线程还是单线程?  回复  更多评论   

2010-07-10 16:32 by hoodlum1980
虽然可能需要的计算量是固定的,但是在单核上的多线程和单线程也是不一样的。采用多线程和单线程主要影响你的任务被系统调度的情况。

# re: 多线程还是单线程?  回复  更多评论   

2010-09-05 12:40 by xghost
单进程有个很明显的问题:怎么处理好阻塞操作?

# re: 多线程还是单线程?  回复  更多评论   

2013-09-06 12:11 by 啦啦啦
@xghost
这个最不是问题

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


OldJiang.com