libevent源码阅读笔记——通用时间队列

​由于libevent支持 /dev/poll, kqueue(2), event ports, POSIX select(2), Windows select(), poll(2), and epoll(4).多平台网络IO,所以根据不同平台,也定义了不同eventop对象,它们被统一放入结构体指针数组eventops[]里。
libevent运用二进制形式,区分5种事件类型。event_add 函数用于添加超时、读、写、信号事件。超时事件由程序内部主动触发。老版本的超时事件的元素存在一个红黑树中,新版本引入了最小堆和队列共同来进行管理。下面介绍的都是libevent2.0.21版本内容。
先来介绍下对超时的管理,libevent用小根堆存储所有的超时时间,但是小根堆的时间复杂度为log(N),为了进一步提高效率,libevent采用了queue对相同超时间隔的Timer事件进行组织。Timer触发时间=当前绝对时间+超时间隔。所以具有相同超时间隔的Timer事件,它们的触发时间是不同的,可以按照升序排列在一起。
event_base_init_common_timeout函数用于初始化通用时间队列。

const struct timeval *
event_base_init_common_timeout(struct event_base *base,
    const struct timeval *duration)
{
    int i;
    struct timeval tv;
    const struct timeval *result=NULL;
    struct common_timeout_list *new_ctl;

    EVBASE_ACQUIRE_LOCK(base, th_base_lock);
    //有MICROSECONDS_MASK位的时间需要去除MICROSECONDS_MASK位才是真实的超时间隔
    if (duration->tv_usec > 1000000) {
        memcpy(&tv, duration, sizeof(struct timeval));
        if (is_common_timeout(duration, base))
            tv.tv_usec &= MICROSECONDS_MASK;
        tv.tv_sec += tv.tv_usec / 1000000;
        tv.tv_usec %= 1000000;
        duration = &tv;
    }
    //判断超时间隔tv是否已经存在于通用时间队列中
    for (i = 0; i < base->n_common_timeouts; ++i) {
        const struct common_timeout_list *ctl =
            base->common_timeout_queues[i];
        if (duration->tv_sec == ctl->duration.tv_sec &&
            durati
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值