这一章其实是对服务器定时器管理的几种实现方案,包括有序链表、时间轮以及小根堆。内容不再详述,下面是摘录自原文的源码。
代码清单11-2:升序定时器链表
#ifndef LST_TIMER
#define LST_TIMER
#include <time.h>
#define BUFFER_SIZE 64
class util_timer;
struct client_data
{
struct sockaddr_in address;
int sockfd;
char buf[BUFFER_SIZE];
util_timer* timer;
};
// 定时器类--链表节点
struct util_timer
{
util_timer():prev(NULL), next(NULL), user_data(NULL){
}
void (*cb_func)(client_data*); //回调函数
time_t expire; // 任务超时时间
client_data* user_data;
util_timer* prev;
util_timer* next;
};
// 定时器链表 升序、双向链表 且带有头节点和尾节点
class sort_timer_lst
{
public:
sort_timer_lst():head(NULL), tail(NULL){
}
// 析构时候删除所有计时器
~sort_timer_lst()
{
util_timer* tmp = head;
while (tmp)
{
head = tmp->next;
delete tmp;
tmp = head;
}
}
// 添加定时器到链表中
void add_timer(util_timer* timer)
{
if (!timer)
{
return;
}
if (head == NULL)
{
head = tail = timer;
return;
}
add_timer(timer, head);
}
// 定时器任务发生变化,调整在链表中的位置。此函数只考虑超时延长的情况
void adjust_timer(util_timer* timer)
{
if (!timer)
{
return;
}
util_timer* tmp = timer->next;
if (!tmp || timer->expire < tmp->expire)
{
return;
}
if (timer == head)
{
head = timer->next;
head->prev == NULL;
timer->next = NULL;
add_timer(timer, head);
}
else
{
timer->prev->next = timer->next;
timer->next->prev = timer->prev;
timer->next = NULL;
timer->prev = NULL;
add_timer(timer, timer->next);
}
}
//从链表中移除
void del_timer(util_timer* timer)
{
if (!timer)
{
return;
}
if (timer == head)
{
if (timer == tail)
{
delete timer;
head = tail = NULL;
timer = NULL;
return;
}
head = head->next;
head->prev = NULL;
delete timer;
timer = NULL;
return;
}
if (timer == tail)
{
tail = tail->prev;
tail->next = NULL;
delete timer;
timer = NULL;
return;
}
timer->prev->next = timer->next;
timer->next->prev = timer->prev;
delete timer;
timer = NULL;
return;
}
// 在tick中处理链表上到期的任务 tick由SIGALRM信号驱动
void tick()
{
if (!head)
{
return;
}
printf("timer tick\n");
//当前系统时间
time_t cur = time(NULL);
//遍历处理到期任务
util_timer* tmp = head;
while (tmp)
{
if (cur < tmp->expire)
{
break;
}
//执行回调
tmp->cb_func(tmp->user_data);
//执行完删除
head = head->next;
if (head