libevent学习笔记四:Libevent整体处理流程

libevent学习笔记四:Libevent整体处理流程

    前面介绍了基本概念、Reactor模式等,为了进一步的深入学习,本节从基本使用场景和代码的整体处理流程入手进一步深入学习。

1 、基本流程

      使用libevnet的基本流程,实际上是 libevent基本应用场景,也就是使用livevent设置定时器等,然后执行附带的几个要求的步骤,应用程序只需要执行下面几个简单的步骤即可。

1)初始化libevent库,获得返回的指针

struct event_base * base = event_init();

即初始化一个Reactor实例;初始化libevent后,接下来就可以注册事件了。

 

2)初始化事件event,设置回调函数和事件,并自动关联。

evtimer_set(&ev, timer_cb, NULL);

这个等价于调用下面的方法

event_set(&ev, -1, 0, timer_cb, NULL);

event_set的函数原型是:

void event_set(struct event *ev, int fd, short event, void (*cb)(int, short, void *), void *arg)

各参数的具体说明如下:

ev:执行要初始化的event对象;
fd:该event绑定的句柄,对于信号事件,它就是关注的信号;
event:在该fd上关注的事件类型,它可以是EV_READ, EV_WRITE, EV_SIGNAL;
cb:这是一个函数指针,当fd上的事件event发生时,调用该函数执行处理,它有三个参数,调用时由event_base负责传入,按顺序,实际上就是event_set时的fd, event和arg;
arg:传递给cb函数指针的参数;
     由于定时事件不需要fd,并且定时事件是根据添加时(event_add)的超时值设定的,因此这里event也不需要设置。相当于初始化一个event handler,在libevent中事件类型保存在event结构体中。需要强调的是libevent并不会管理event事件集合,需要应用程序自行管理;

3)设置event从属的event_base

event_base_set(base, &ev);  

在这里指明了event要注册到哪个event_base实例上;

4)添加事件

event_add(&ev, timeout);

    前面基本信息都已设置完成,剩下的就是简单的调用event_add()函数即可完成,其中timeout是定时值;相当于调用Reactor::register_handler()函数注册事件。

 

5)程序进入无限循环处理过程,等待就绪事件并执行事件处理

event_base_dispatch(base);

 

 2、实例代码

前面文字介绍的流程和处理步骤,综合下来就是下面一段代码:

 struct event ev;
 struct timeval tv;

 void time_cb(int fd, short event, void *argc)
 {
     printf("timer wakeup/n");
     event_add(&ev, &tv); // reschedule timer
 }

 int main()
 {
     struct event_base *base = event_init();
     tv.tv_sec = 10; // 10s 时间间隔
     tv.tv_usec = 0;
     evtimer_set(&ev, time_cb, NULL);
     event_add(&ev, &tv);
     event_base_dispatch(base);
 }

 

3、事件处理流程说明

当应用程序向libevent注册一个事件后,按照下面的图就给出的逻辑执行基本流程。
    1)第一步应用程序准备并初始化event,设置好事件类型和回调函数;
    2)向libevent添加该事件event。对于定时事件,libevent使用一个小根堆管理,key为超时时间;对于Signal和I/O事件,libevent将其放入到等待链表(wait list)中,这是一个双向链表结构;
    3)程序调用event_base_dispatch()系列函数进入无限循环,等待事件,以select()函数为例;每次循环前libevent会检查定时事件的最小超时时间tv,根据tv设置select()的最大等待时间,以便于后面及时处理超时事件;
当select()返回后,首先检查超时事件,然后检查I/O事件;
Libevent将所有的就绪事件,放入到激活链表中;
然后对激活链表中的事件,调用事件的回调函数执行事件处理;

 

4、总结

      上面介绍了libevent的简单实用场景和基本流程,很简单的说明了libevent的事件处理流程,以使学习者对libevent有了基本的概念,后面汇总介绍libevent的事件管理框架(即:Reactor模式中的Reactor框架)再做详细的介绍。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Libevent是一个事件驱动的网络编程框架,而event.h是其核心头文件之一。该头文件定义了事件处理相关的结构体、函数和宏等内容。 下面是event.h中常用的一些定义和函数: ### 1.事件回调函数 ```c typedef void (*event_callback_fn)(evutil_socket_t fd, short events, void *arg); ``` 该类型定义了事件回调函数的原型,其中fd是事件所在的文件描述符,events是事件类型,arg是用户传入的参数。 ### 2.事件结构体 ```c struct event { event_callback_fn ev_callback; // 事件回调函数 int ev_fd; // 事件所在的文件描述符 short ev_events; // 事件类型 short ev_res; // 事件结果 struct event_base *ev_base; // 事件所属的event_base void *ev_arg; // 用户传入的参数 }; ``` 该结构体表示一个事件,其中ev_callback是事件回调函数,ev_fd是事件所在的文件描述符,ev_events是事件类型,ev_res是事件结果,ev_base是事件所属的event_base,ev_arg是用户传入的参数。 ### 3.事件类型 ```c #define EV_TIMEOUT 0x01 #define EV_READ 0x02 #define EV_WRITE 0x04 #define EV_SIGNAL 0x08 #define EV_PERSIST 0x10 #define EV_ET 0x20 ``` 该宏定义了事件类型,分别为超时事件、读事件、写事件、信号事件、持续事件和边缘触发事件。 ### 4.事件处理函数 ```c struct event_base *event_base_new(void); int event_base_dispatch(struct event_base *base); int event_base_loopexit(struct event_base *base, const struct timeval *tv); void event_base_free(struct event_base *base); ``` 这些函数用于创建event_base、处理事件、退出事件循环和释放event_base等操作。 以上是event.h中的一些常用内容,更多细节可以查看源码和官方文档。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jyl_sh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值