对于游戏服务器来说 定时器必不可少,我们设计定时器的方法一般有两种:
一种是设计一个定时器队列。对定时器的超时时间进行排序,每次在服务器的帧循环中从头开始检查定时器是否超时,如果超时了,把定时器从队列中移除,然后执行定时器回调函数,如果没有超时直接跳出循环。最简单的是我们利用STL库的map容器,map容器的内部实现是红黑树,遍历的时候是从小到大遍历, 我们把定时器的下次执行时间作为键, 每次在帧循环里遍历map容器,如果键小于当前时间则超时了,我们就执行定时器内容,然后删除定时器继续往后遍历。 如果键大于当前时间则没有超时直接跳出遍历。优化的版本是我们设计一个普通的队列,每次检查最小的超时时间,如果超时了就执行定时器,继续检查直到没有超时。而每次我们检查时会找出最小的那个时间节点,所以我们用最小堆算法,每次只查找最小的。这样不需要在每次的插入删除时进行排序,但是每次检查时需要求出最小的那个时间节点。
另一种是在帧上面做的定时器(原理上是个时间轮),这里我根据游戏服务器的特点,自己做了特殊的定时器。超时时间跟帧绑定,比如:我们的逻辑帧时间间隔时30ms, 而我们将在2000ms后执行定时器操作, 则我们把超时时间转换成帧数 (2000 + (30 - 1)) / 30 = 67, 意思