libevent事件循环

事件循环


1. 纠正时间,因为用户可能手动更改本地时间,而超时是针对时间点的,这样导致时间不准确,超时事件受到影响。

2. 获取堆顶元素超时时间,与当前时间相减,得到差值,该差值传给epoll,让其最晚在差值时间后返回。

    如果,当前堆顶已经超时了,则直接返回0,让epoll_wait 立即返回。通过这种措施,防止长时间没有IO事件到来,

    epoll 不能返回,超时事件得不到处理。

3. 记录时间点1, tv_cache-> event_tv

4. epoll_wait

5. 记录时间点 2  系统调用获取时间 ->tv_cache

6. 处理超时事件

7. 处理激活队列中事件

 

时间点1的作用:用于时间纠正,此处event_tv 为 tv_cache 的值,在下一轮时间纠正函数处,event_tv < tv_cache的,

如果不是小于,那么进行时间纠正。

缓存时间,可以减少系统调用这样耗时的动作,在时间点2到时间点1的这个阶段,获得的时间都是cache缓存的时间。

所以event_tv作用是缓存tv_cache的值,用于纠正时间。


时间更正

static void
timeout_correct(struct event_base *base, struct timeval *tv)
{
    struct event **pev;
    unsigned int size;
    struct timeval off;

    // 采用monotonic 不需要纠正
    if (use_monotonic)
        return;

    /* 由于时间缓存,此处tv 即为 tv_cache值 */
    gettime(base, tv);
    if (evutil_timercmp(tv, &base->event_tv, >=)) {
        base->event_tv = *tv;
        return;
    }
    /* off 为时间差值 */
    evutil_timersub(&base->event_tv, tv, &off);
    /* 时间根堆所有超时时间都要调整,减去off*/
    pev = base->timeheap.p;
    size = base->timeheap.n;
    for (; size-- > 0; ++pev) {
        struct timeval *ev_tv = &(**pev).ev_timeout;
        evutil_timersub(ev_tv, &off, ev_tv);
    }
    /* Now remember what the new time turned out to be. */
    base->event_tv = *tv;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值