libevent之events分析

参考博客:https://blog.csdn.net/windeal3203/article/details/52772233

1.event 状态

event:主要分为三种状态及转换:initialized、pending、active

  • 关联base=>initialized状态
  • event_add=>pending状态
  • 触发事件,调用回调=>active状态
  • event_del=>非pendding状态(可以理解为初始化状态)
  • active状态(persistent属性)=>pending状态
  • active状态(不含persistent属性)=>非pendding状态(可以理解为初始化状态)
    在这里插入图片描述
2.event 使用流程
  • 初始化事件event_new 、event_assign
  • 注册事件 event_add
  • 监听事件 event_base_dispatch
  • 删除事件 event_del
  • 释放事件 event_free
3.初始化event

对于已经在event_base中处于“挂起”状态的event,永远不要调用event_assign。这样做会导致极为难以诊断的错误。如果event已经初始化,并且处于“挂起”状态,那么在调用event_assign之前应该先调用event_del。*

//申请内存创建event ,内部使用event_assign赋值
struct event *event_new(struct event_base *, evutil_socket_t, short, event_callback_fn, void *);

//只是对event赋值,不申请内存。只能在event非pending or非active 才能操作,否则不安全
int event_assign(struct event *, struct event_base *, evutil_socket_t, short, event_callback_fn, void *);

//释放event,如果event处于pending or active,将会事先使其变为 non-pending  and non-active,然后释放
void event_free(struct event *);

event 事件类型:

#define EV_TIMEOUT 0x01 /*定时事件*/
#define EV_READ 0x02 /*I/O事件*/
#define EV_WRITE 0x04 /*I/O事件*/
#define EV_SIGNAL 0x08 /*信号*/
#define EV_PERSIST 0x10 /*永久事件 */
#define EV_ET 0x20 /*边沿触发*/

EV_PERSIST 属性:
	默认情况下,当一个“挂起”的event变为“激活”时(要么是因为fd准备好读或写,要么是超时时间到),
那么在它的回调函数执行之前,它就会变为“非挂起”状态。因此,如果希望再次使event变为“挂起”状态,可以在回调函数内
部再次调用event_add函数。 
  如果event设置了EV_PERSIST标志,那么event就是“持久”的。这意味着event在回调函数激活的时候,依然保持“挂起”
状态。如果希望在回调函数中将event变为“非挂起”状态,则可以调用event_del函数。
  当event的回调函数运行时,“持久”event的超时时间就会被重置。因此,如果某个event标志为EV_READ|EV_PERSIST,
并且将超时时间设置为5秒,则该event在下面的条件发生时,会变为“激活”:当该socket准备好读时; 距离上次event变为
激活状态后,又过了5秒钟. 
4.注册事件
int event_add(struct event *ev, const struct timeval *tv);

如果是一个(non-pending)未注册ev,调用event_add函数会注册该事件(变为pending状态)。如果是一个(pending)注册过的ev,调用该函数会在tv时间后重新注册该事件。成功返回0,失败返回-1。

5.监听事件
int event_base_dispatch(struct event_base *base);

内部调用的event_base_loop,

//@param: flags
//等待IO事件
#define EVLOOP_ONCE 0x01
//非阻塞,直接返回
#define EVLOOP_NONBLOCK 0x02 
//其他的线程中添加事件
#define EVLOOP_NO_EXIT_ON_EMPTY 0x04

int event_base_loop(struct event_base *base, int flags);

如果需要退出loop:

//延迟tv时间后,停止event loop
int event_base_loopexit(struct event_base *base, const struct timeval *tv);
//立刻停止,等同于tv = NULL
int event_base_loopbreak(struct event_base *base);

//获取退出方式
int event_base_got_exit(struct event_base *base);
int event_base_got_break(struct event_base *base);
6.其他event事件
  1. 查找正在运行的事件(event_base_get_running_event)
  2. 设置事件执行一次(event_base_once)
  3. 激活事件(event_active)
  4. event_base信息和状态写入文件(event_base_dump_events)
7、创建一个可以将自身作为回调函数参数的的event
//该函数返回一个“魔术”指针,使得event_new创建一个本身就能作为回调函数参数的event。
void*event_self_cbarg();

NOTE:当前版本的Libevent,对于大多数的后端方法来说,同一时间,每个进程仅能有一个event_base可以用来监听信号。如果一次向两个event_base添加event,即使是不同的信号,也仅仅会只有一个event_base可以接收到信号。对于kqueue来说,不存在这样的限制。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值