最近看了一下定时器的实现方式主要有链表,最小堆,还有就是Timing-Wheel定时器方式,自己实现了一个Timing-Wheel定时器,求拍砖
主要数据结构:
/*定时器节点*/
struct timer_node{
timer_id id; /*定时器id号*/
int interval; /*定时器超时值*/
int solt; /*触发定时器需要的时间片*/
timer_expiry *cb; /*定时器回调函数*/
void *user_data; /*定时器传入参数*/
int len; /*定时器传入参数长度*/
struct timer_node *next;
};
/*定时器管理*/
struct timer{
int time_solt; /*定时器时间片大小*/
int solt_num; /*定时器最大数量*/
int cur_solt; /*定时器当前时间片大小*/
int solt_count; /*定时器累计时间片大小*/
long cur_time; /*定时器当前时间*/
long pre_time; /*定时器上一个时间*/
get_time *gt; /*定时器得到当前时间*/
struct timer_node **timer_list;
} T;
定时器回调函数 :
/*定时器超时函数*/
typedef int timer_expiry(timer_id id, void *user_data, int len);
/*获得当前时间*/
typedef long get_time(void);
timer_node结构中timer_expiry *cb为定时器超时调用的函数,返回0结束定时器,返回1继续循环定时器,这样定时器执行次数控制就非常方便了
timer结构体中get_time *gt为获得当前时间回调函数,如果返回秒即为秒定时器,返回毫秒即为毫秒定时器
具体代码如下:
time.h
time.c
int i = 0;
memset(&T, 0, sizeof(struct timer));
T.gt = gt;
T.timer_list = (struct timer_node **)malloc(num*sizeof(struct timer_node *));
if (0 == T.timer_list){
return -1;
}
while (i < num){
T.timer_list[i] = 0;
i++;
}
T.time_solt = solt;
T.solt_num = num;
return 0;
}
/*销毁所有定时器*/
/*返回值:无*/
void
destroy_timer(){
int i = 0;
struct timer_node *p=0, *q=0;
while(i<T.solt_num){
p = T.timer_list[i];
if(p){
while(p){
q = p;
p = p->next;
free(q);
}
}
i++;
}
free(T.timer_list);
return;
}
/*添加一个定时器*/
/*p:定时器节点指针*/
/*返回值:无*/
void add_timer(struct timer_node *p){
int index = (T.cur_solt + p->interval/T.time_solt)%T.solt_num;
p->solt = T.solt_count + p->interval/T.time_solt;
if (T.timer_list[index]){
p->next = T.timer_list[index];
}
T.timer_list[index] = p;
return;
}
/*添加一个定时器*/
/*id:定时器id用户指定,程序不保证id唯一*/
/*interval:定时器超时值*/
/*cb:定时器超时回调函数*/
/*user_data:传入参数*/
/*len:传入参数长度*/
/*返回值:0成功,-1失败*/
int
add_timer(timer_id id, int interval, timer_expiry *cb, void *user_data, int len){
struct timer_node *p = (struct timer_node *)malloc(sizeof(struct timer_node));
if (0 == p){
return -1;
}
memset(p, 0, sizeof(struct timer_node));
p->cb = cb;
p->id = id;
p->len = len;
p->interval = interval;
p->user_data = user_data;
add_timer(p);
return 0;
}
/*删除一个定时器*/
/*id:定时器id*/
/*返回值:0成功,-1失败*/
int
delete_timer(timer_id id){
return -1;
}
/*循环定时器*/
/*返回值:无*/
void
timer_runonce(){
long diff;
struct timer_node *p=0, *q=0;
T.cur_time = T.gt();
if (0 == T.pre_time){
T.pre_time = T.cur_time;
}
diff = (T.cur_time-T.pre_time)/T.time_solt;
if (diff > 0){
T.pre_time = T.cur_time;
T.cur_solt += diff;
T.solt_count += diff;
if (T.cur_solt>=T.solt_num){
T.cur_solt = 0;
}
}
else{
return;
}
q = T.timer_list[T.cur_solt];
while (q){
p = q;
q = q->next;
if (T.solt_count >= p->solt){
T.timer_list[T.cur_solt] = q;
if (p->cb(p->id, p->user_data, p->len)){
p->next = 0;
add_timer(p);
}
else{
free(p);
}
}
}
return;
}
测试代码testtimer
while(1){
timer_runonce();
Sleep(2000);
}
destroy_timer();
}
int _tmain(int argc, _TCHAR* argv[])
{
detect_memory_leaks(true);
int num = 1024*1024 - rand()%100;
init_timer(num, 1, gt);
// clock_ms tm;
for (int i=1; i<num; i++){
int interval = rand()%30+1;
add_timer(i, interval, cb, 0, 0);
}
// printf("add_timer: %d/n", tm.elapsed());
while (1){
timer_runonce();
}
destroy_timer();
return 0;
}