您的位置:首页 > 编程语言

Libevent解析(二)从简单使用代码剖析建立对Libevent的认识主线

2018-01-01 20:12 316 查看
Libevent解析我的上篇博客从整体宏观流程,对它进行的简单易懂的一个解释,而本篇我想从一个Libevent实例入手,让大家能从整体上去把握软件逻辑和结构,代码如下:

#include<iostream>

#include<event.h>            //Libevent安装后提供的核心库函数

#include<sys/signal.h>

using namespace std;

void signal_cb( int fd, short event, void* argc )     //信号事件的的回调函数(信号事件发生后回调此函数)

{
struct event_base* base = ( event_base* )argc;
struct timeval delay = { 2, 0};
printf("Caught an interrupt signal; exiting cleanly in two seconds...\n");
event_base_loopexit(base, &delay);

}

void timeout_cb(int fd, short event, void* argc)   // 定时事件的回调函数

{
printf("timeout\n");

}

int main()

{
struct event_base* base = event_init();        //创建event_base对象,即相当于创建了一个Reactor实例

struct event* signal_event = evsignal_new(base, SIGINT, signal_cb, base); //创建信号事件处理器,并设置从属Reactor实例
event_add(signal_event, NULL);     //将创建好的信号处理器,注册到事件队列中

timeval tv = {1, 0};
struct event* timeout_event = evtimer_new(base, timeout_cb, NULL);  //创建定时事件处理器
event_add(timeout_event, &tv);   //将创建好的定时事件处理器注册到事件队列中

event_base_dispatch(base);    //开始执行事件循环

event_free(timeout_event);    // 释放资源
event_free(signal_event);
event_base_free(base);

return 0;

}

我想之前对Libevent有了解,对我上篇博客有研究,结合注释了解这个实例程序问题不大;我再将程序中关键点作说明:

1)event_init函数等都由libevent所提供函数库event.h提供;event_init函数用于创建event_base的一个对象,这是事件能被处理的基础架构函数;相当于Reactor的实例,从此就可以去创建时间处理器,之后通过创建的reactor对事件处理器进行统一管理分发等操作;

2)创建具体的事件处理器,(事件处理器,是对事件句柄,回调函数,事件类型的封装;之后便可以交给Reactor处理管理操作),代码中的evsignal_new()和evtimer_new()分别是创建信号和时间事件处理器,同时也指定了所创建事件处理器所属Reactor;

      evsignal_new()和evtimer_new()是定义在include/event2/event.h文件中的宏;

       #define evsignal_new(b, x, cb, arg)   event_new{(b), (x), EV_SIGNAL|EV_PERSIST, (cb), (arg) }

       #define  evtimer_new(b,cb, arg)        event_new{(b), -1, 0 (cb), (arg) }              由此可以看出来,其实他们两个函数创建事件处理器时候,其实用到的是同一个创建函数event_new去创建,它的函数定义如下:

          struct  event*  event_new(struct event_base*  base,  evutil_socket_t  fd,  short  events,

                                                              void  (*cb)  (evutil_socket_t,  short,  void*),  void arg)

         base是指定创建事件所属Reactor,fd是事件处理器关联句柄(注意的是定时事件fd传-1,I/O事件是文件描述符值,信号事件的fd是信号值)(events参数还指定了其他事件爱那类型,可选值都定义在include/event2/event.h文件中);

cb是指定目标事件对应的回调函数,arg是给Reactor传给回调函数的参数;

3)调用event_add函数,是将事件处理器添加到注册事件队列中进行管理,相当于之前说的Reactor中的register_handler;

4)调用event_base_dispatch是来执行事件循环,注释中也有说明;

5)事件循环结束后,调用*_free系列函数进行系统资源释放。

我想看到这里,已经对Lievent使用提供了一个认识的主线,也又一遍对它从整体上有了一个认知;Libevent源代码有许多文件代码,负责不同的事件处理的部分(比如数据结构部分,I/O复用的各种方式实现,整体框架实现等很多部分),源代码中会从一个一个细节出发,之后也会进行剖析;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: