对任何一个网络库,定时器功能都非常重要,libhv当然也不例外,今天先对目前我所使用的定时器功能做一个简单说明。
libhv主要提供了三个接口使用定时器,添加、删除和重置,还有一个htimer_add_period,目前没用过,先不说了。。。。
htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout, uint32_t repeat DEFAULT(INFINITE));
void htimer_del(htimer_t* timer);
void htimer_reset(htimer_t* timer);
首先看htimer_add
//cb:回调函数
//timeout:定时时间
//repeat:重复次数
htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout, uint32_t repeat) {
if (timeout == 0) return NULL;
htimeout_t* timer;
HV_ALLOC_SIZEOF(timer); //申请定时器所用内存
timer->event_type = HEVENT_TYPE_TIMEOUT; //设置事件类型
timer->priority = HEVENT_HIGHEST_PRIORITY; //设置优先级
timer->repeat = repeat; //定时器的重复次数
timer->timeout = timeout; //超时时间
hloop_update_time(loop); //修复可能由于修改系统时间导致的时间偏差
timer->next_timeout = hloop_now_hrtime(loop) + timeout*1000; //定时器的绝对时间
heap_insert(&loop->timers, &timer->node); //插入堆中
EVENT_ADD(loop, timer, cb); //将定时器事件加入loop
loop->ntimers++; //定时器加1
return (htimer_t*)timer; //返回定时器
}
上一篇说定时器具有最高优先级,就是在这里设置的,将定时器的优先级设置为HEVENT_HIGHEST_PRIORITY。其他的在上面都加了比较详细的注释,比较重要的就是定时器采用的就是前面的博客中说明的堆结构。该堆的初始化为:
heap_init(&loop->timers, timers_compare);
static int timers_compare(const struct heap_node* lhs, const struct heap_node* rhs) {
return TIMER_ENTRY(lhs)->next_timeout < TIMER_ENTRY(rhs)->next_timeout;
}
可以看到,定时器是在堆中按照到期时间进行排序的。以上就是添加一个定时器,在说明删除和重置之前,想先对处理定时器的方式简单说明一下,因为感觉更加重要。
上一篇博客提到过,在事件处理接口hloop_process_events中,会优先处理定时器:
// calc blocktime
int32_t blocktime = HLOOP_MAX_BLOCK_TIME;
if (loop->timers.root) { //判断是否为空