定时器
定时器应⽤
- ⼼跳检测
- 技能冷却
- 武器冷却
- 倒计时
- 其它需要使⽤超时机制的功能
定时器概述
对于服务端来说,驱动服务端逻辑的事件主要有两个,⼀个是⽹络事件,另⼀个是时间事件;
在不同框架中,这两种事件有不同的实现⽅式;
第⼀种,⽹络事件和时间事件在⼀个线程当中配合使⽤;例如nginx、 redis;
第⼆种,⽹络事件和时间事件在不同线程当中处理;例如skynet;
定时器设计
接⼝设计
// 初始化定时器
void init_timer();
// 添加定时器
Node* add_timer(int expire, callback cb);
// 删除定时器
bool del_timer(Node* node);
// 找到最近要发⽣的定时任务
Node* find_nearest_timer();
// 更新检测定时器
void update_timer();
// 清除定时器
// void clear_timer();
要点:
- 有序的结构,且增加删除操作不影响该结构有序;
- 能快速查找最⼩节点;
- 时间轮增加操作只从单个定时任务触发,忽略定时任务之间的⼤⼩关系;⽽红⿊树、最⼩
堆、跳表的有序性依赖定时任务之间的⼤⼩关系;
数据结构选择
-
红⿊树
对于增删查,时间复杂度为 ;对于红⿊树最⼩节点为最左侧节点,时间复杂度为O(\({log_2{n}}\))
-
最⼩堆
对于增查,时间复杂度为O(\({log_2{n}}\));对于删时间复杂度为O(n),但是可以通过辅助数据结构(map或者hashtable来快速索引节点)来加快删除操作;对于最⼩节点为根节点,时间复杂度为O(1);
-
时间轮
对于增删查,时间复杂度为O(1);查找最⼩节点也为O(1);