1、入门

1.1、概述
Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络库。Libevent有几个显著的亮点:
(1)事件驱动(event-driven),高性能;
(2)轻量级,专注于网络,不如 ACE 那么臃肿庞大;
(3)源代码相当精炼、易读;
(4)跨平台,支持 Windows、Linux、*BSD和 Mac Os;
(5)支持多种 I/O多路复用技术, epoll、poll、dev/poll、select 和kqueue 等;
(6)支持 I/O,定时器和信号等事件;
(7)注册事件优先级;
 Libevent 已经被广泛的应用,作为底层的网络库;比如 memcached、 Vomi t、 Nylon、 Netchat等等。

 

1.2、一个简单示例

 1 int lasttime;
 2 
 3 static void
 4 timeout_cb(int fd, short eventvoid *arg)
 5 {
 6 struct timeval tv;
 7 struct event *timeout = arg;
 8 int newtime = time(NULL);
 9 
10 //printf("%s: called at %d: %d\n", __func__, newtime,
11 printf("%s: called at %d: %d\n""timeout_cb", newtime,
12         newtime - lasttime);
13 lasttime = newtime;
14 
15 evutil_timerclear(&tv);
16 tv.tv_sec = 2;
17 //重新注册event
18 event_add(timeout, &tv);
19 }
20 
21 int
22 main (int argc, char **argv)
23 {
24 struct event timeout;
25 struct timeval tv;
26  
27 /* Initalize the event library */
28 //初始化event环境
29 event_init();
30 
31 /* Initalize one event */
32 //设置事件
33 evtimer_set(&timeout, timeout_cb, &timeout);
34 
35 evutil_timerclear(&tv);
36 tv.tv_sec = 2;
37 //注册事件
38 event_add(&timeout, &tv);
39 
40 lasttime = time(NULL);
41     
42 //等待,分发,处理事件
43 event_dispatch();
44 
45 return (0);
46 }

这是一个简单的基于libevent的定时器程序,运行结果:

libevent源码分析 

用libevent编程非常简单,只需要调用event_init初始化环境,然后调用event_add注册相应的事件,接着调用event_dispatch等待并处理相应的事件即可。
调用event_add注册事件时,设置其回调函数。Libevent检测到事件发生时,便会调用事件对应的回调用函数,执行相关的业务逻辑。

1.3、源代码结构
Libevent 的源代码虽然都在一层文件夹下面,但是其代码分类还是相当清晰的,主要可分为头文件、内部使用的头文件、辅助功能函数、日志、libevent 框架、对系统 I/O 多路复用机制的封装、信号管理、定时事件管理、缓冲区管理、基本数据结构和基于 libevent的两个实用库等几个部分,有些部分可能就是一个源文件。
(1)头文件
主要就是 event.h:事件宏定义、接口函数声明,主要结构体 event 的声明;
(2)内部头文件
xxx-internal.h:内部数据结构和函数,对外不可见,以达到信息隐藏的目的;
(3)libevent框架
event.c:event 整体框架的代码实现;
(4)对系统 I/O多路复用机制的封装
epoll.c:对 epoll 的封装;
select.c:对 select 的封装;
devpoll.c:对 dev/poll 的封装;
kqueue.c:对kqueue 的封装;
(5)定时事件管理
min-heap.h:其实就是一个以时间作为 key的小根堆结构;
(6)信号管理
signal.c:对信号事件的处理;
(7)辅助功能函数
evutil.h  和 evutil.c:一些辅助功能函数,包括创建 socket pair和一些时间操作函数:加、减和比较等。
(8)日志
log.h和 log.c:log 日志函数
(9)缓冲区管理
evbuffer.c 和buffer.c:libevent 对缓冲区的封装;
(10)基本数据结构
compat\sys 下的两个源文件: queue.h是 libevent 基本数据结构的实现,包括链表,双向链表,队列等;_libevent_time.h:一些用于时间操作的结构体定义、函数和宏定义;
(11)实用网络库
     http 和evdns:是基于 libevent 实现的http 服务器和异步 dns 查询库;

2、核心对象
结构体event和event_base是libevent的两个核心数据结构,前者代表一个事件对象,后者代表整个事件处理框架。
2.1、event(事件)

 1 //event.h
 2 struct event {
 3 TAILQ_ENTRY (event) ev_next;          //已注册事件链表
 4 TAILQ_ENTRY (event) ev_active_next;//就绪事件链表
 5 TAILQ_ENTRY (event) ev_signal_next; //signal链表
 6 unsigned int min_heap_idx;    /* for managing timeouts,事件在堆中的下标 */
 7 
 8 struct event_base *ev_base;
 9 
10 int ev_fd;      //对于I/O事件,是绑定的文件描述符;对于signal事件,是绑定的信号
11 short ev_events; //event关注的事件类型
12 short ev_ncalls; //事件就绪执行时,调用 ev_callback 的次数
13 short *ev_pncalls;    /* Allows deletes in callback */
14 
15 struct timeval ev_timeout;  //timout事件的超时值
16 
17 int ev_pri;   /* smaller numbers are higher priority,优先级 */
18 
19 void (*ev_callback)(intshortvoid *arg); //回调函数
20 void *ev_arg; //回调函数的参数
21 
22 int ev_res;        /* result passed to event callback */
23 int ev_flags; //event的状态
24 };
25 

相关文章: