libevent 核心:事件 event

libevent 的核心-event

Libevent 是基于事件驱动( event-driven )的,从名字也可以看到event 是整个库的核心。event 就是Reactor 框架中的事件处理程序组件;它提供了函数接口,供Reactor 在事件发生时调用,以执行相应的事件处理,通常它会绑定一个有效的句柄。
首先给出event 结构体的声明,它位于event.h 文件中:
struct event {
TAILQ_ENTR (Yevent ) ev_next ;
TAILQ_ENTR (Yevent ) ev_active_next ;
TAILQ_ENTR (Yevent ) ev_signal_next ;
unsigned int min_heap_idx ; /* for managing timeouts /
struct event_base * ev_base;
int ev_fd ;
short ev_events ;
short ev_ncalls ;
short * ev_pncalls ; /
Allows deletes in callback /
struct timeval ev_timeout ;
int ev_pri ; /
smaller numbers are higher priority /
void (
ev_callback )( int , short , void * arg );
void * ev_arg;
int ev_res ; /* result passed to event callback /
int ev_flags ;
};
1) ev_events: event关注的事件类型,它可以是以下3种类型:
I/O 事件: EV_WRITE 和EV_READ
定时事件: EV_TIMEOUT
信号: EV_SIGNAL
辅助选项: EV_PERSIST ,表明是一个永久事件
可以看出事件类型可以使用“ |”运算符进行组合,需要说明的是,信号和I/O 事件不能同时设置;
2) ev_next, ev_active_next 和ev_signal_next 都是双向链表节点指针;它们是libevent 对不同事件类型和在不同的时期,对事件的管理时使用到的字段。
libevent 使用双向链表保存所有注册的I/O 和Signal 事件, ev_next 就是该I/O 事件在链表中的位置;称此链表为“已注册事件链表” ;同样ev_signal_next 就是signal 事件在signal 事件链表中的位置;ev_active_next : libevent 将所有的激活事件放入到链表active list 中,然后遍历active list 执行调度, ev_active_next 就指明了event 在active list 中的位置;
3) min_heap_idx 和ev_timeout,如果是timeout 事件,它们是event 在小根堆中的索引和超时值, libevent 使用小根堆来管理定时事件
4)ev_base 该事件所属的反应堆实例,这是一个event_base结构体;
5) ev_fd ,对于I/O 事件,是绑定的文件描述符;对于signal 事件,是绑定的信号;
6) ev_callback, event 的回调函数,被ev_base 调用,执行事件处理程序,这是一个函数指针,原型为:
void (
ev_callback )( int fd , short events , void * arg )
其中参数fd 对应于ev_fd; events 对应于ev_events; arg 对应于ev_arg;
7) ev_arg:void* ,表明可以是任意类型的数据,在设置event 时指定;
8) eb_flags: libevent 用于标记event 信息的字段,表明其当前的状态,可能的值有:
#define EVLIST_TIMEOUT 0x01 // event 在time 堆中
#define EVLIST_INSERTED0x02 // event 在已注册事件链表中
#define EVLIST_SIGNAL 0x04 // 未见使用
#define EVLIST_ACTIVE 0x08 // event 在激活链表中
#define EVLIST_INTERNAL0x10 // 内部使用标记
#define EVLIST_INIT 0x80 // event 已被初始化
9) ev_ncalls:事件就绪执行时,调用ev_callback 的次数,通常为1;
10) ev_pncalls:指针,通常指向ev_ncalls 或者为NULL ;
11) ev_res:记录了当前激活事件的类型;

libevent 对event 的管理

从event 结构体中的3 个链表节点指针和一个堆索引出发,大体上也能窥出libevent 对event 的管理方法了,可以参见下面的示意图。
每次当有事件event 转变为就绪状态时, libevent 就会把它移入到active event list[priority]中,其中priority 是event 的优先级;
接着libevent 会根据自己的调度策略选择就绪事件,调用其cb_callback() 函数执行事件处理;并根据就绪的句柄和事件类型填充cb_callback 函数的参数。
在这里插入图片描述

事件设置的接口函数

要向libevent 添加一个事件,需要首先设置event 对象,这通过调用libevent 提供的函数有: event_set(), event_base_set(), event_priority_set() 来完成;下面分别进行讲解。
void event_set ( struct event * ev, int fd , short events , void (* callback )( int , short , void *), void * arg )
1.设置事件ev 绑定的文件描述符或者信号,对于定时事件,设为-1 即可;
2.设置事件类型,比如EV_READ|EV_PERSIST, EV_WRITE, EV_SIGNAL 等;
3.设置事件的回调函数以及参数arg;
4.初始化其它字段,比如缺省的event_base和优先级;
int event_base_set ( struct event_base * base, struct event * ev)
设置event ev 将要注册到的event_base;libevent 有一个全局event_base 指针current_base ,默认情况下事件ev将被注册到current_base 上,使用该函数可以指定不同的event_base;如果一个进程中存在多个libevent 实例,则必须要调用该函数为event 设置不同的event_base;
int event_priority_set ( struct event * ev, int pri )
设置event ev的优先级,没什么可说的,注意的一点就是:当ev正处于就绪状态时,不能设置,返回-1。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值