近来,对WOW现有的模拟器的看法又有了新的变化。
话说Ascent的性能相当不错,比起Mangos,我想这点异议不大吧。Trinity不加评论,没有实际测试。
Ascent接触了很久,运行机制也算比较了解,但是始终有个遗憾。
先简述一下结构:IOCP负责网络IO,多线程处理,加入封包队列。
主循环(单线程)更新每个会话,读取封包,并交给对应的handle函数(还是主循环的线程)。
周期完毕,检查如果花的时间短,等待再进入下个更新周期,超时了则马上进入下个周期。
问题就在此产生:
一、Ascent的线程池形同虚设,现有的线程池其实只是个Manager或Container,并没有发挥线程池的作用。线程池存在的理由就是避免为新的请求产生和销毁线程造成开销,循环利用线程。
二、分析一下服务器的工作类型。
按照《C++网络编程,卷一》,第五章,第一节中三种服务器类型的定义,循环、并发及反应式服务器。
Ascent是不折不扣的反应式服务器,同时也属于循环式,该类型结构最适合:1.短期服务;2.不经常运行的服务
“由于这样一种循环式结构,每一个请求处理都会在一个相对粗糙的层次上被串行化-例如,在应用程序和OS同步事件多路分离程序之间的接口上。但是,这种粗糙层次上的并发性不会充分利用主机平台上的某些处理资源和OS特性”—— 《C++网络编程,卷一》,5.1节
如此说来,Ascent性能并不佳,提升的空间还很大。
但事情没这么简单,性能无法单纯用架构衡量。考虑一个问题,如果多线程应答封包会发生什么。
我曾尝试将处理多线程化,双开wow进去跑,差不多10分钟左右,服务器就会发生死锁,屡试不爽。
原因很简单,作为网游服务器,需要同步的数据太多了,我们曾被unordered_XXX系列的boost库容器玩疯了。
完美的同步都会发生数据结构损坏,出现坏链表,简直匪夷所思。
推想下去,如果真的多线程并行处理,那么同步量会大到令人发指,几乎所有数据都需要同步,多到令我觉得干脆按类串行化得了。
真羡慕Windows的可重入API的设计,如果Win的API不是可重入的。。。
技术上讲,认为,寻求一种稳定的并行构架是模拟器的目标。