libevent简单介绍:
libevent是一个用C语言编写的事件通知库。有着卓越的性能,可移植性强,跨平台,轻量级,专注于网络,支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,定时器和信号等事件;注册事件优先级。
event_base事件集合:
event_base是event的一个集合,event_base中存放你是监听是否就绪的event。一般情况下一个线程有一个event_base,多个线程的情况下需要开多个event_base,event_base主要是用来管理和实现事件的监听循环。
创建方法
struct event_base *event_base_new(void);
销毁方法
void event_base_free(struct event_base *base);
重新初始化
int event_reinit(struct event_base *base);
event 事件:
event_base是事件的集合,负责事件的循环,以及集合的销毁。而event就是event_base中的基本单元:事件。
创建事件:
struct event *event_new(struct event_base *, evutil_socket_t, short, event_callback_fn, void *);
参数分别为:
1,event_base,
2,文件描述符/信号,
3,所关心的事件类型,
4,触发事件的回调函数,
5,传给回调函数的参数(用户自定义数据)
回调函数原型:
void (*event_callback_fn)(evutil_socket_t, short, void *);
参数
1,文件描述符,
2,事件类型,
3,用户自定义数据,
事件类型:
#defineEV_TIMEOUT 0x01 // 超时
#defineEV_READ 0x02 // event 相关的文件描述符可以读了
#defineEV_WRITE 0x04 // event 相关的文件描述符可以写了
#defineEV_SIGNAL 0x08 // 被用于信号检测
#defineEV_PERSIST 0x10 // 类似epoll水平触发
#defineEV_ET 0x20 // 边缘触发
注册事件:
int event_add(struct event *ev, const struct timeval *timeout);
参数
1,创建的事件,
2,超时,
删除/释放事件:
int event_del(struct event *);
event_del并不是真正意义上的释放内存,该函数会将事件转为非pending和非activing的状态。
void event_free(struct event *);
真正意义的释放内存。
处理事件:
int event_base_dispatch(struct event_base *);
不断的循环监听注册上来的事件。
int event_base_loop(struct event_base *, int);
event_base_loop这个方法会比event_base_dispatch这个方法更加灵活一些。
第二个参数
EVLOOP_ONCE:
阻塞直到有一个活跃的event,然后执行完活跃事件的回调就退出。
EVLOOP_NONBLOCK :
不阻塞,检查哪个事件准备好,调用优先级最高的那一个,然后退出。
0:
如果参数填了0,则只有事件进来的时候才会调用一次事件的回调函数,比较常用。
事件循环停止的情况:
1. event_base中没有事件event
2. 调用event_base_loopbreak(),那么事件循环将停止
3. 调用event_base_loopexit(),那么事件循环将停止
4. 程序错误,异常退出
两个方法区别:
1. event_base_loopexit(base, NULL) 如果当前正在为多个活跃事件调用回调函数,那么不会立即退出,而是等到所有的活跃事件的回调函数都执行完成后才退出事件循环
2. event_base_loopbreak(base) 如果当前正在为多个活跃事件调用回调函数,那么当前正在调用的回调函数会被执行,然后马上退出事件循环,而并不处理其他的活跃事件了。
tips:
1,每一个事件event都需要通过event_new初始化生成。event_new生成的事件是在堆上分配的内存。
2,当一个事件通过event_add被注册到event_base上的时候,这个事件处于pending(等待状态),当只有有事件进来的时候,event才会被激活active状态,相关的回调函数就会被调用。
3,persistent 如果event_new中的what参数选择了EV_PERSIST,则是持久的类型。持久的类型调用完回调函数后,会继续转为pending状态,就会继续等待事件进来。大部分情况下会选择持久类型的事件。
4,而非持久的类型的事件,调用玩一次之后,就会变成初始化的状态。这个时候需要调用event_add 继续将事件注册到event_base上之后才能使用。
网友评论