9.7.3 定时器的实现

定时器是通过一棵红黑树实现的。ngx_event_timer_rbtree就是所有定时器事件组成的红黑树,而ngx_event_timer_sentinel就是这棵红黑树的哨兵节点,如下所示。


ngx_thread_volatile ngx_rbtree_t ngx_event_timer_rbtree;

static ngx_rbtree_node_t ngx_event_timer_sentinel;


这棵红黑树中的每个节点都是ngx_event_t事件中的timer成员,而ngx_rbtree_node_t节点的关键字就是事件的超时时间,以这个超时时间的大小组成了二叉排序树ngx_event_timer_rbtree。这样,如果需要找出最有可能超时的事件,那么将ngx_event_timer_rbtree树中最左边的节点取出来即可。只要用当前时间去比较这个最左边节点的超时时间,就会知道这个事件有没有触发超时,如果还没有触发超时,那么会知道最少还要经过多少毫秒满足超时条件而触发超时。先看一下定时器的操作方法,见表9-5。

9.7.3 定时器的实现 - 图1

9.7.3 定时器的实现 - 图2

事实上,还有两个宏与ngx_event_add_timer方法和ngx_event_del_timer方法的用法是完全一样的,如下所示。


define ngx_add_timer ngx_event_add_timer

define ngx_del_timer ngx_event_del_timer


从表9-5可以看出,只要调用ngx_event_expire_timers方法就可以触发所有超时的事件,在这个方法中,循环调用所有满足超时条件的事件的handler回调方法。那么,多久调用一次ngx_event_expire_timers方法呢?这个时间频率可以部分参照ngx_event_find_timer方法,因为ngx_event_find_timer会告诉用户下一个最近的超时事件多久后会发生。

在9.8.5节中,读者会看到ngx_event_expire_timers究竟什么时候会被调用。