libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名分布式缓存软件memcached也是libevent based,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。
例如 : 客户端连接到服务端属于一个连接的事件,当这个事件触发的时候就会去处理。
event_base是event的一个集合,主要是用来管理和实现事件的监听循环。一般情况下一个线程一个event_base,多个线程的情况下需要开多个event_base。
创建event_base
struct event_base *event_base_new(void);
销毁event_base
void event_base_free(struct event_base *base);
初始化event_base
int event_reinit(struct event_base *base);
销毁event_base
void event_base_free(struct event_base *base);
IO多路复用模型中 (IO模型文章),有多种方法可以供我们选择,但是这些模型是在不同的平台下面的: select poll epoll kqueue devpoll evport win32
当我们创建一个event_base的时候,libevent会自动为我们选择最快的IO多路复用模型,Linux下一般会用epoll模型。
获取io多路复用模型名称
const char *event_base_get_method(const struct event_base *base);
事件循环监听event_loop event_base是需要监听的event事件集合,需要循环被监听
监听函数
int event_base_dispatch(struct event_base *base);
int event_base_loop(struct event_base *base, int flags);
event事件
even_base中的基本单元,事件。
例如 socket进行网络开发的时候,都会使用accept这个方法来阻塞监听是否有客户端socket连接上来,如果客户端连接上来,则会创建一个线程用于服务端与客户端进行数据的交互操作,而服务端会继续阻塞等待下一个客户端socket连接上来,客户端连接到服务端实际就是一种事件。
创建event
struct event *event_new(struct event_base *base, evutil_socket_t fd,short what, event_callback_fn cb,void *arg);
参数:
1. base:即event_base
2. fd:文件描述符。
3. what:event关心的各种条件。
4. cb:回调函数。
5. arg:用户自定义的数据,可以传递到回调函数中去。
libevent是基于事件的,也就是说只有在事件到来的这种条件下才会触发当前的事件。例如:
1. fd文件描述符已准备好可写或者可读
2. fd马上就准备好可写和可读。
3. 超时的情况 timeout
4. 信号中断
5. 用户触发的事件
释放event_free
void event_free(struct event *event);
注册event
int event_add(struct event *ev, const struct timeval *tv);
信号事件 信号事件也可以对信号进行事件的处理。用法和event_new类似。只不过处理的是信号
// base --- event_base // signum --- 信号,例如 SIGHUP // callback --- 信号出现时调用的回调函数 // arg --- 用户自定义数据 evsignal_new(base, signum, cb, arg) //将信号 event 注册到 event_base evsignal_add(ev, tv) // 清理信号 event evsignal_del(ev)
1. 每一个事件event都需要通过event_new初始化生成。event_new生成的事件是在堆上分配的内存。
2. 当一个事件通过event_add被注册到event_base上的时候,这个事件处于pending(等待状态),当只有有事件进来的时候,event才会被激活active状态,相关的回调函数就会被调用。
3. persistent 如果event_new中的what参数选择了EV_PERSIST,则是持久的类型。持久的类型调用玩回调函数后,会继续转为pending状态,就会继续等待事件进来。大部分情况下会选择持久类型的事件。
3. 而非持久的类型的事件,调用玩一次之后,就会变成初始化的状态。这个时候需要调用event_add 继续将事件注册到event_base上之后才能使用。