大部分云端的后台服务,经常会使用到定时器功能来检测一些状态值的变化,且当定时器较多时,就需要设计统一的定时器管理模块来维护所有的定时器资源。然而要设计性能良好的定时器和管理模块,是需要一定的经验和技巧的,所以,姑且在此炫技一回,分享一下定时器模块设计的方法,主要从数据结构的角度来考虑。
采用自下而上的层次来设计,首先将每个定时器作为一个定时器节点的数据结构,结构体如下所示:
struct Node { time_t start_time; //上一次触发的时间,用于比较是否到点 int timerId; //定时器id,唯一标识 int timeVal; //间隔多少秒执行一次 int count; //当前触发次数 int total; //总的触发次数 bool type; //是否无限循环 bool isUsed; //是否被使用了 Timer* timerObj; //执行定时任务的处理对象,其他使用到定时器的类需要以Timer作为基类 Node* next_node; Node* prev_node;}
定时器节点管理模块如下所示:
class Manager { Node* nodes; //指向所有节点构成的数组的指针 int maxCount; //最大时间节点的数目 int idleCount; //空闲的时间节点数目 Node idleHead; //空闲节点的第一个节点,当申请创建新时间节点时,从这里取 Node usedHead; //当对所有定时器进行循环检测时,从这里开始}
其对外提供的接口有:
- 设置并启动定时器
- 检测所有定时器任务是否间隔时间已经达到,达到后,则调用timerObj多态继承的基类函数来执行定时任务。
写在最后:为了使整个定时管理模块能够运行起来,应该设置一个线程来周期性的检测所有定时任务时间是否到达,一般情况会每秒检测一下,同时会与epoll网络模型结合起来用。