nginx 源码学习笔记(二十三)—— event 模块(四) ——timer红黑树

在二十一节中,提到过调用ngx_eventfind_timer()获取timer,然后传递给epoll模块,做等待时间,今天我们主要讲解下这个方法。

本文来自于:http://blog.csdn.net/lengzijian


nginx中的timer用红黑树的结构排序。ngx_event_timer_rbtree就是nginx中timer的红黑树。

1.下面我们来看一下ngx_event_timer_rbtree的结构:

src/core/ngx_rbtree.h typedef struct ngx_rbtree_s ngx_rbtree_t; typedef void (*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); struct ngx_rbtree_s { ngx_rbtree_node_t *root; //根节点 ngx_rbtree_node_t *sentinel; //哨兵节点 ngx_rbtree_insert_pt insert; //插入方法指针 };

2.树中节点的结构:

src/core/ngx_rbtree.h typedef ngx_uint_t ngx_rbtree_key_t; typedef ngx_int_t ngx_rbtree_key_int_t; typedef struct ngx_rbtree_node_s ngx_rbtree_node_t; struct ngx_rbtree_node_s { ngx_rbtree_key_t key; ngx_rbtree_node_t *left; //左节点 ngx_rbtree_node_t *right; //右节点 ngx_rbtree_node_t *parent; //父节点 u_char color; //当前节点颜色 u_char data; //当前节点数据 };

3.ngx_event_find_timer函数:

src/event/ngx_event_timer.c ngx_msec_t ngx_event_find_timer(void) { ngx_msec_int_t timer; ngx_rbtree_node_t *node, *root, *sentinel; //如果根节点地址等于哨兵将节点地址,返回-1 if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) { return NGX_TIMER_INFINITE; } //对ngx_event_timer_mutex上锁 ngx_mutex_lock(ngx_event_timer_mutex); root = ngx_event_timer_rbtree.root; sentinel = ngx_event_timer_rbtree.sentinel; //获取最小的timer界定 node = ngx_rbtree_min(root, sentinel); //解锁 ngx_mutex_unlock(ngx_event_timer_mutex); //用最小值的timer节点的值减去ngx_current_mses值 timer = (ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_msec; return (ngx_msec_t) (timer > 0 ? timer : 0); }

nginx中,当前所有可能被触发的定时器被保存在红黑树这种数据结构中,通过红黑树,你可以很快的得到距离当前最快发生的定时器时间的时间差,将这个时间差作为select/poll/epoll等函数的参数,也就是说最多等待这么长时间就返回。得到函数调用总共花费了多少时间,根据这个时间取出红黑树的根节点比较查看是否应该触发该定时器时间,如果可以,则将定时器从红黑树中删除,然后继续查看新的成为树根的定时器的节点,这个过程一直进行下去,知道没有定时器满足被触发条件,也就是还没有被触发的事件。


nginx中,新接收了一个连接,就会保存这个连接上来的时间,并且以这个时间来加入红黑树定时器。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值