Libev源码分析05:Libev中的绝对时间定时器

本文详细分析了Libev中的绝对时间定时器ev_periodic,探讨了其数据结构、设置方法、如何启动和停止,以及在时间调整时的处理策略。ev_periodic基于日历时间,其超时时间可通过三种方式设置,包括使用回调函数、按间隔重复或设定一次性触发。文中通过实例展示了不同设置下的超时触发情况。

        Libev中的超时监视器ev_periodic,是绝对时间定时器,不同于ev_timer,它是基于日历时间的。比如如果指定一个ev_periodic在10秒之后触发(ev_now() + 10),然后将系统时间调整为去年的一月一号,则该定时器会在一年后才触发超时事件。(ev_timer依然会在10秒之后触发)

 

一:数据结构

         超时监视器ev_ periodic结构:

typedef struct ev_periodic
{
    int active; 
    int pending;
    int priority;
    void *data;
    void (*cb)(struct ev_loop *loop, struct ev_periodic *w, int revents);  
    ev_tstamp at;

    ev_tstamp offset; /* rw */
    ev_tstamp interval; /* rw */
    ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_THROW; /* rw */
} ev_periodic;

         可见其中的前六个成员与ev_timer和ev_watcher_time是一样的。与ev_timer类似,ev_periodic中的active也标明该监视器在堆数组periodics中的下标;at表明超时事件触发的时间点,共有三种设置方法,而且offset、interval和reschedule_cb都是用来设置触发时间的,这个会在下面说明。

 

二:监视器函数

1:设置超时监视器

#define ev_periodic_set(ev,ofs_,ival_,rcb_)  do {\
  (ev)->offset = (ofs_); \
  (ev)->interval = (ival_); \
  (ev)->reschedule_cb = (rcb_); \
 }while (0)

#define ev_periodic_init(ev,cb,ofs,ival,rcb) do {\
   ev_init ((ev), (cb)); \
   ev_periodic_set ((ev),(ofs),(ival),(rcb)); \
 } while (0)

2:启动监视器ev_periodic_start

void ev_periodic_start (struct ev_loop *loop, ev_periodic *w)
{
    if (expect_false (ev_is_active (w)))
        return;

    if (w->reschedule_cb)
        ev_at (w) = w->reschedule_cb (w, ev_rt_now);
    else if (w->interval)
    {
        assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.));
        periodic_recalc (EV_A_ w);
    }
    else
        ev_at (w) = w->offset;


    ++periodiccnt;
    ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
    array_needsize (ANHE, periodics, periodicmax, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值