libevent源码学习(四)定时器Timer

来源:互联网 发布:淘宝好看的跑步鞋店铺 编辑:程序博客网 时间:2024/05/16 07:02

与signal相比,Timer事件的集成会直观和简单很多。

集成到事件主循环

因为系统的I/O机制像selectepoll_wait都允许程序制定一个超时时间:

//int select(int nfds, fd_set *readfds, fd_set *writefds,                  fd_set *exceptfds, struct timeval *timeout);//int epoll_wait(int epfd, struct epoll_event *events,                      int maxevents, int timeout);

即使没有I/O事件的发生,也能保证系统调用在Timeout时间内返回。

那么根据所有timer事件的最小超时时间来设置系统I/O的timeout时间,当系统I/O返回时,再激活所有就绪的Timer事件就可以了。

event_base_loop事件循环中,我们很轻易就能找到timeout_next函数

这个函数根据堆中具有最小超时值的事件和当前时间来计算等待时间

static inttimeout_next(struct event_base *base, struct timeval **tv_p){    /* Caller must hold th_base_lock */    struct timeval now;    struct event *ev;    struct timeval *tv = *tv_p;    int res = 0;    //堆的首元素具有最小的超时值    ev = min_heap_top(&base->timeheap);    if (ev == NULL) {    //没有超时事件,则不进行超时等待,事件循环将一直阻塞直到有IO事件发生        /* if no time-based events are active wait for I/O */        *tv_p = NULL;        goto out;    }    //取得当前时间    if (gettime(base, &now) == -1) {        res = -1;        goto out;    }    //如果超时事件<=当前值,不能等待,需要立即返回    //宏真是任性 可以直接用<= 表示小于等于operator    if (evutil_timercmp(&ev->ev_timeout, &now, <=)) {        evutil_timerclear(tv);        goto out;    }    //计算等待的时间=当前时间-最小超时时间    //这是对timersub的简单封装    evutil_timersub(&ev->ev_timeout, &now, tv);    EVUTIL_ASSERT(tv->tv_sec >= 0);    EVUTIL_ASSERT(tv->tv_usec >= 0);    event_debug(("timeout_next: in %d seconds", (int)tv->tv_sec));out:    return (res);}

小根堆

Libevent使用堆来管理Timer事件。向堆中插入、删除元素的时间复杂度都是O(lgN),而获取最小值的时间复杂度是O(1),
堆用数组的形式维护一个完全二叉树,这是堆的基本概念,下面看两个典型实现(伪代码):

heap[size++]=new;child=size;while(child > 0){    parent=(child-1)/2;    if(heap[parent].key<heap[child].key)        break;    swap(parent,child)}

libevent用的办法和stl一样,新元素来时,为新元素预留了一个位置hole,通过比较key和parent,不断的上溯hole,最后确认hole就是新元素应该在的位置时,
才会真正的执行插入操作。

hole=size;while(hole>0){    parent=(hole-1)/2;    if(heap[parent].key<new.key)        break;    heap[hole]=heap[parent];    hole=parent;}heap[hole]=new;size++;

参考

http://blog.csdn.net/zhangxiao93/article/details/72461396

原创粉丝点击