对于定时器事件,Libevent采用两种方法处理定时器:
1、定时器尾队列
2、时间堆
在event结构体中,定义了联合体类型ev_timeout_pos来指明定时器的位置
//仅用于定时事件处理器:当为通过定时器时,ev_next_with_common_timeout指向定时器队列中的位置
//当为其它定时器时,min_heap_idx为指向时间堆中的索引
union {
TAILQ_ENTRY(event) ev_next_with_common_timeout;
int min_heap_idx;
} ev_timeout_pos;
开发者认为有时候使用简单的链表(通用定时器)来管理定时器将具有更高的效率。如下所述:
当需要获取多个具有同一超时值的定时器时,定时器链表比时间堆效率更高,此处个人理解为:若超时时间相同,在定时器链表中,可以通过顺序遍历的方法获取超时的定时器,而采用时间堆的话,每获取一个定时器需要维护堆,时间复杂度为nlogn。
一个定时器是否是通用定时器取决于其超时值(超时值由具体超时值、幻数5以及定时器索引组成),具体由is_common_timeout函数决定:
/* Common timeouts are special timeouts that are handled as queues rather than
* in the minheap. This is more efficient than the minheap if we happen to
* know that we're going to ge