Libevent源码分析-----管理超时event

本文详细介绍了Libevent中common-timeout的用途、原理、相关结构体及其使用方法,阐述了如何将超时event存放到common-timeout中,以及common-timeout与小根堆的配合工作,旨在理解Libevent如何高效管理超时event。
摘要由CSDN通过智能技术生成

        转载请注明出处: http://blog.csdn.net/luotuo44/article/details/38678333



        前面的博文已经说到,如果要对多个超时event同时进行监听,就要对这些超时event进行集中管理,能够方便地(时间复杂度小)获取、加入、删除一个event。

        在之前的Libevent版本,Libevent使用小根堆管理这些超时event。小根堆的插入和删除时间复杂度都是O(logN)。在2.0.4-alpha版本时,Libevent引入了一个叫common-timeout的东西来管理超时event,要注意的是,它并不是替代小根堆,而是和小根堆配合使用的。事实上,common-timeout的实现要用到小根堆。

 

        Libevent的小根堆和数据结构教科书上的小根堆几乎是一样的。看一下数据结构和Libevent的小根堆源码,很容易就懂的。这样就不多讲了。


        本文主要讲一下common-timeout。从common的字面意思和它的实际使用来说,可以把它翻译成“公用超时”。


common-timeout的用途:

        要讲解common-timeout,得先说明它的用途。前面说到它和小根堆是配合使用的。小根堆是用在:多个超时event的超时时长是随机的。而common-timeout则是用在: 大量的超时event具有相同的超时时长。其中,超时时长是指event_add参数的第二个参数。 要注意的是,这些大量超时 event 虽然有相同的超时时长,但它们的超时时间是不同的。因为超时时间 = 超时时长+ 调用event_add时间。

        毫无疑问,如果有相同超时时长的大量超时event都放到小根堆上,那么效率比较低的。虽然小根堆的插入和删除的时间复杂度都是O(logN),但是如果有大量的N,效率也是会下降很多。


common-timeout的原理:

        common-timeout的思想是,既然有大量的超时event具有相同的超时时长,那么就它们必定依次激活。如果把它们按照超时时间升序地放到一个队列中(在Libevent中就是这样做的),那么每次只需检查队列的第一个超时event即可。因为其他超时event肯定在第一个超时之后才超时的。

        前面说到common-timeout和小根堆是配合使用的。从common-timeout中选出最早超时的那个event,将之插入到小根堆中。然后通过小根堆对这个event进行超时监控。超时后再从common-timeout中选出下一个最早超时的event。具体的超时监控处理过程可以参考《超时event的处理》一文。通过这样处理后,就不用把大量的超时event都插入到小根堆中。


        下面看一下Libevent的具体实现吧。

 

相关结构体:

        首先看一下event_base为common-timeout提供了什么成员变量。

//event-internal.h文件
struct event_base {
	//因为可以有多个不同时长的超时event组。故得是数组
	//因为数组元素是common_timeout_list指针,所以得是二级指针
	struct common_timeout_list **common_timeout_queues;
	//数组元素个数
	int n_common_timeouts;
	//已分配的数组元素个数
	int n_common_timeouts_allocated;
};

struct common_timeout_list {
	//超时event队列。将所有具有相同超时时长的超时event放到一个队列里面
	struct event_list events;

	struct timeval duration;//超时时长
	struct event timeout_event;//具有相同超时时长的超时event代表
	struct event_base *base;
};

        在实际应用时,可能超时时长为10秒的有1k个超时event,时长为20秒的也有1k个,这就需要一个数组。数组的每一个元素是common_timeout_list结构体指针。每一个common_timeout_list结构体就会处理所有具有相同超时时长的超时event。

        common_timeout_list结构体里面有一个event结构体成员,所以并不是从多个具有相同超时时长的超时event

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值