libevent库学习总结(一)——基础
一、基础
1.1、 介绍
Libevent是一个用于开发可伸缩网络服务器的事件通知库。Libevent API提供了一种机制来执行回调函数,当某个特定事件发生在文件描述符上或超时到达之后。此外,Libevent还支持信号或定期超时的回调。
Libevent的目的是取代在事件驱动的网络服务器中发现的事件循环。应用程序只需调用eventbasedispatch()(p122),然后动态地添加或删除事件,而无需更改事件循环。
目前Libevent支持 /dev/poll, kqueue(2), select(2), poll(2), epoll(4), and evports。内部事件机制完全独立于公开的事件API,而Libevent的简单更新无需重新设计应用程序就可以提供新的功能。因此,Libevent允许可移植的应用程序开发,并提供了一个操作系统上可用的最可伸缩的事件通知机制。Libevent也可以用于多线程程序。Libevent可以在Linux、BSD、Mac OS X、Solaris和Windows上编译。
1.2、 规范用法
使用Libevent的每个程序都必须包括 < event2/event.h (p.108) >,并将-levent标志传递给链接器。(如果您只想要主事件,并缓冲 IO-based的代码,而不希望链接任何协议代码,则可以链接-leventcore。)
1.3、 库设置
在调用任何其他Libevent函数之前,需要设置这个库。如果要在多线程应用程序的多个线程中使用Libevent,则需要初始化对线程的支持——使用evthread_use_pthreads() (p.203)or evthread_use_windows_threads() (p.203)。参见< event2/thread.h (p.199) >
可以用event_set_mem_functions替换Libevent的内存管理功能;使用 event_enable_debug_mode() (p.136)来启用调试模式。
1.4、 创建一个基础事件(event base)
使用event_base_new()(p.129) 或者 event_base_new_with_config() (p.130)来创建一个event_base (p.17) 结构体。eventbase(p.17)负责跟踪哪些事件是“待处理的”以及哪些事件是“活动的”。每个事件都与单个event_base(p.17)相关联。
1.5、 事件通知
对于希望监视的每个文件描述符,必须使用event_new() (p.139)创建一个event结构体。(您还可以声明一个event结构体,并调用event_assign() (p.121)来初始化该结构体的成员。想要使能通知,您可以通过调用 event_add() (p.120)将该结构体添加到监视事件的列表中。event结构体必须在活动时保持分配,因此通常应该在堆上分配它。
1.6、 事件调度
最后,使用event_base_dispatch() (p.122)来循环和调度事件。可以使用event_base_loop() (p.127)来获取更细粒度的控制。(细粒度控制是将业务模型中的对象加以细分,从而得到更科学合理的对象模型,直观的说就是划分出很多对象。)
如果只有一个线程可以一次调度一个给定的event_base (p.17)。如果想同时在多个线程中运行多个事件,可以有一个单独的event_base (p.17),event_base中的事件将工作添加到一个工作队列中,或者可以创建多个event_base (p.17)对象。
1.7、I/O缓冲
1.7.1、Libevent在常规的事件回调之上提供了一个缓冲的输入/输出。这个抽象称为bufferevent。bufferevent提供输入和输出缓冲区,这些缓冲区被自动填充和流出。缓冲事件的用户不再直接处理输入输出,而是从输入和写入输出缓冲区中读取数据。
1.7.2、通过bufferevent_socket_new() (p.76)来初始化bufferevent结构体。
1.7.3、使用 bufferevent_enable() (p.65) 和bufferevent_disable() (p.65)来使能和禁止使用 I/O缓冲。
1.7.4、使用 bufferevent_read()(p.71) 和bufferevent_write() (p.77)来代替对socket的直接读写。
1.7.5、 当可以读取时,bufferevent将尝试从文件描述符读取并调用读取回调。当输出缓冲区空时,写回调就会被执行,而在默认情况下是0。
1.8、 定时器
Libevent还可以用于创建计时器,时间过期后调用回调。 evtimer_new()宏返回一个event结构体,用作定时器。使用evtimer_add()来激活计时器。计时器可以通过调用evtimer_del()来关闭。(这些宏都是event_new()(p 139)、event_add()(第120)和event_del(第135页)的简单封装。)
1.9、DNS异步解析
Libevent提供了一个异步的DNS解析器,它可以代替非标准的DNS解析器函数。详见 < event2/dns.h (p.81) >。
1.10、事件驱动型的HTTP服务器
Libevent提供了一个非常简单的事件驱动型的HTTP服务器,它可以嵌入到您的程序中,并用于服务HTTP请求。
需要添加头文件 < event2/http.h (p.147) >。
1.11、RPC服务器和客户机的框架
Libevent为创建RPC服务器和客户端提供了一个框架。它负责封送和解封所有的数据结构。
1.12、头文件
- event2/event.h (p.108) libevent的主头文件
- event2/thread.h (p.199) 用于多线程程序
- event2/buffer.h (p.25) event2/bufferevent.h (p.54) 读写的缓冲区管理
- event2/util.h (p.203)可移植的非阻塞网络代码的实用功能
- event2/dns.h (p.81) DNS异步解析
- event2/http.h (p.147) 嵌入式HTTP服务器
- event2/rpc.h (p.181) 创建RPC服务器和客户机的框架