3.1、首先初始化libevent库,并保存返回的指针
@param ev an event struct to be modified//事件的结构体,也就是定时器事件timeout
@param base the event base to which ev should be attached.//需要绑定的event_base
@param fd the file descriptor to be monitored//需要监视文件描述符,当fd=-1时,事件被手动激活或者定时器溢出激活
@param events desired events to monitor; can be EV_READ and/or EV_WRITE//事件的模式
@param callback callback function to be invoked when the event occurs//回调函数,
,当fd上的事件event发生时,调用该函数执行处理,它有三个参数,调用时由event_base负责传入,按顺序,实际上就是event_assign
的fd, event和arg;
arg:传递给cb函数指针的参数
@param callback_arg an argument to be passed to the callback function//传给回调函数的参数
struct event_base *base = event_base_new();
这一步相当于初始化一个Reactor实例;在初始化libevent后,就可以注册事件了。
3.2、定义两个结构体,分别代表事件和定时器值
struct event timeout;//定时器事件
struct timeval tv;//定时器值
3.3、将事件和event_base绑定
event_assign(&timeout, base, -1, flags, timeout_cb, (void*)&timeout);
flags参数代表了事件标志。
#define EV_TIMEOUT 0x01//这个标志表示某超时时间流逝后事件成为激活的。构造事件的时候,EV_TIMEOUT标志是被忽略的:可以在添加事件的时候设置超时,也可以不设置。超时发生时,回调函数的what参数将带有这个标志。
#define EV_READ 0x02//表示指定的文件描述符已经就绪,可以读取的时候,事件将成为激活的。
#define EV_WRITE 0x04//表示指定的文件描述符已经就绪,可以写入的时候,事件将成为激活的。
#define EV_SIGNAL 0x08//用于实现信号检测
#define EV_PERSIST 0x10//表示事件是“持久的”
#define EV_ET 0x20//表示如果底层的event_base后端支持边沿触发事件,则事件应该是边沿触发的。这个标志影响EV_READ和EV_WRITE的语义。
我们可以去看下event_assign函数:
int event_assign(struct event *, struct event_base *, evutil_socket_t, short,event_callback_fn, void *);
来看下各个参数:
3.4、在创建定时器事件时,使用的是struct event timeout,也可以用event_new函数动态分配,这样就不需要
event_assign函数了。
struct event *timeout;
timeout= evsignal_new(base, -1, flags, timeout_cb, (void*)&timeout);
在分配后可以用event_free来释放
3.5、添加事件
event_add(&timeout, &tv);
3.6、
程序进入无限循环,等待就绪事件并执行事件处理
event_base_dispatch(base);
3.7、为使用方便,libevent提供了一些以evtimer_开头的宏,用于替代event_*调用来操作纯超时事件。使用这些宏能改进代码的清晰性。
#define evtimer_assign(ev, b, cb, arg) \
event_assign((ev), (b), -1, 0, (cb), (arg))
#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
#define evtimer_add(ev, tv) event_add((ev), (tv))
#define evtimer_del(ev) event_del(ev)
#define evtimer_pending(ev, tv) event_pending((ev), EV_TIMEOUT, (tv))
#define evtimer_initialized(ev) event_initialized(ev)
3.8、程序代码
#include "stdafx.h"
#include <winsock2.h>
#include <event2/event-config.h>
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/util.h>
static void timeout_cb(evutil_socket_t fd, short event, void *arg)
{
struct event *timeout;
timeout = (struct event *)arg;
struct timeval tv;
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(timeout, &tv);
printf("timeout\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
struct event_base *base = event_base_new();
struct event timeout;//定时器事件
struct timeval tv;//定时器值
int flags = EV_TIMEOUT;
event_assign(&timeout, base, -1, flags, timeout_cb, (void*)&timeout);
evutil_timerclear(&tv);
tv.tv_sec = 2;
tv.tv_usec = 0;
event_add(&timeout, &tv);
event_base_dispatch(base);
return 0;
}