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复用的各种方式实现,整体框架实现等很多部分),源代码中会从一个一个细节出发,之后也会进行剖析;
#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复用的各种方式实现,整体框架实现等很多部分),源代码中会从一个一个细节出发,之后也会进行剖析;
相关文章推荐
- [Android | 小代码] 天气预报 简易Demo json解析数组+对象 Gson+Volley简单使用
- 使用autotools建立Makefile简单实例解析
- Github的简单使用代码托管(建立自己的仓库实现代码的上传与版本管理)
- 使用autotools建立Makefile简单实例解析
- 一只简单的网络爬虫(基于linux C/C++)————Url处理以及使用libevent进行DNS解析
- 使用autotools建立Makefile简单实例解析
- 使用libevent写的一个简单服务器的代码
- TinyXML使用解析(一)——文件的建立
- 深度解析ASP.NET2.0中的Callback机制callback的一般使用方法还算简单,直接参照
- 简单使用 cvCalcPCA 计算主成分的代码
- 使用Digester解析XML文件简单范例
- 在代码中使用biztalk类库建立Message和Part
- 在代码中使用biztalk类库建立Message和Part
- js编码规范:使用JSDoc建立JavaScript代码的文档
- Apache Hook机制解析(下)——实战:在自己的代码中使用Apache的钩子
- 个人学习代码保存:例8.在存储过程中使用简单的事务处理
- WTL7.5在VC8中的使用简单剖析
- Beginning C# Objects从概念到代码——1.4 解析一个简单的C#程序
- [收藏]使用DOM操作XML文档的简单范例代码
- 一个简单的动态编译器,支持C#和VB.NET。当你想测试一些简单的代码的时候可以使用。