Libevent 编程- 定时器事件(timer event)

时间:2022-09-16 00:14:21

Libevent 编程- 定时器事件(timer event)

本文介绍Libevent 三种事件之一的定时器事件。 该事件可以用来注册定时事件和周期性事件。Libevent 根据所有定时器事件的最小超时时间来设置系统 I/O 的 timeout 值,当系统I/O 返回时,再激活就绪的定时器事件,如此 Timer 事件便可融合在系统 I/O 机制中。
定时器事件的实现基于一种经典的数据结构-小根堆,相关的数据结构定义和操作在minheap-internal.h中。其处理与其他两种事件类似。 不同之处在于定时器事件不依赖于文件描述符,在初始化该类型事件时,文件描述符处的参数为-1,在注册定时器事件是,后面的时间参数不为 NULL。如下:

event_assign(&ev_time, base, -1, flags, timeout_cb, (void*)&ev_time); //初始化定时器事件ev_time,准备注册到base
event_add(&ev_time, &tv);//注册定时器事件
下面是 Libevent 的自身测试代码 :
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/util.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct timeval lasttime;
static int event_is_persistent;

static void timeout_cb(evutil_socket_t fd, short events, void *arg) {
struct timeval newtime, difference;
evutil_gettimeofday(&newtime, NULL);
evutil_timersub(&newtime, &lasttime, &difference);
double elapsed = difference.tv_sec + (difference.tv_usec / 1.0e6);

printf("timeout_cb called at %d: %.3f seconds elapsed.\n",
(int)newtime.tv_sec, elapsed);
lasttime = newtime;

if(event_is_persistent) {
struct event* ev_time = arg;
struct timeval tv;
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(ev_time, &tv);
}
}

int main(int argc, char *argv[])
{
int flags;
if(2 == argc && !strcmp(argv[1], "-p")) {
event_is_persistent = 1;
flags = EV_PERSIST;
} else if(1 == argc) {
event_is_persistent = 0;
flags = 0;
} else {
printf("Usage: %s [-p]\n", argv[0]);
exit(EXIT_FAILURE);
}

struct event ev_time;
struct event_base *base = event_base_new();
event_assign(&ev_time, base, -1, flags, timeout_cb, (void*)&ev_time);

struct timeval tv;
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(&ev_time, &tv);

evutil_gettimeofday(&lasttime, NULL);

event_base_dispatch(base);
event_base_free(base);

exit(EXIT_SUCCESS);
}

我对测试代码作了些小改动,全局变量event_is_persistent是标志周期事件的开关,程序提供前面提到的两种 timer 事件,关于注册周期性事件我查看了 Libevent 的一些资料发现所谓周期事件就是重复注册 timer 事件,刚开始接触 timer 事件时,我一直以为 event_add函数的第二个时间参数表示周期,等自己尝试过后才发现那个值表示 timeout。以下是程序编译运行结果:
Libevent 编程- 定时器事件(timer event)

允许转载