异步事件处理库-libevent
2011-01-07 14:31:35 阿炯

libevent是一个异步事件处理程序库,以BSD许可证释出。


libevent提供了一组应用程序编程接口(API),让程式设计师可以设定某些事件发生时所执行的函式,也就是说,libevent可以用来取代网络服务器所使用的循环检查架构。

由于可以省去对网络的处理,且拥有不错的效能,有些软件使用libevent作为网络底层的函式库,如:memcached、Tor。

The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts.

libevent is meant to replace the event loop found in event driven network servers. An application just needs to call event_dispatch() and then add or remove events dynamically without having to change the event loop.

Currently, libevent supports /dev/poll, kqueue(2), event ports, select(2), poll(2) and epoll(4). The internal event mechanism is completely independent of the exposed event API, and a simple update of libevent can provide new functionality without having to redesign the applications. As a result, Libevent allows for portable application development and provides the most scalable event notification mechanism available on an operating system. Libevent can also be used for multi-threaded applications; see Steven Grimm's explanation. Libevent should compile on Linux, *BSD, Mac OS X, Solaris and Windows.



libevent是一个用来开发可扩展的网络服务器的事件通知函数库。当一个文件描述符上的特定事件发生或是一个超时时间到达后,libevent API提供一种执行回调函数的机制。而且,libevent还支持基于信号或定期超时的回调功能。它旨在替换在原有事件驱动网络服务器事件循环而设计的,应用程序仅仅需要调用event_dispatch(),然后动态地添加或是移除事件就可以了,而不需要改变原有的事件循环。

目前,libevent支持/dev/poll,kqueue(2),select(2),poll(2)和epoll(4)等高并发网络编程模型。而它对实时信号的支持正处于实验性阶段。内部的事件处理机制是完全独立于暴露出来的API的,并且新功能的加入并不需要重新设计应用程序,而是仅仅需要做一个简单的libevent更新即可。因此,lievent允许可移植性的应用程序开发,并且能够提供适合特定操作系统的最具可扩展性的事件通知机制。libevent同时也可用于多线程编程环境,更多说明请看Steven Grimm的说明。libevent可以在Linux,*BSD,Mac OS X,Solaris和Windows系统上编译。

标准用法

每一个使用libevent的程序,都需要包含头文件,并且需要传递-levent标志给连接器linker。在使用任何库函数之前,需要先调用event_init()或者event_base_new()函数制执行一次libevent库的初始化。

事件通知

对于每一个你想监视的文件描述符,你必须声明一个事件结构并且调用event_set()去初始化结构中的成员。为了激活通知,你需要通过调用event_add()将该结构添加到监视事件列表。只要是该事件存活,那么就需要保持该已allocated的事件结构,因此该事件结构需要在堆(heap)上申请。最后,需要调用event_dispatch()函数循环和调度事件。

I/O缓冲区

libevent提供了一个定期回调事件顶层的抽象。该抽象被称为缓冲事件(buffered event)。缓冲事件提供自动地填充和流掉(drained)的输入和输出缓冲区。缓冲时间的用户不再需要直接操作I/O,取而待之的是仅仅从输入缓冲区读,向输出缓冲区写就可以了。一旦通过bufferevent_new()进行了初始化,bufferevent结构就可以通过bufferevent_enable()和bufferevent_disable()重复地使用了。作为替代,对一个套接口的读写需要通过调用bufferevent_read()和bufferevent_write()函数来完成。当由于读事件而激活bufferevent时,那么后续将会自动回调读函数从该文件描述符读取数据。写函数将会被回调,无论何时这个输出缓冲区空间被耗尽到低于写的下水位(low watemark),通常该值默认为0。

定时器

libevent通过创建一个定时器来参与到一个经过一定超时时间后的回调事件中。evtimer_set()函数将准备(分配)一个事件结构被用于作为一个定时器。为了激活定时器,需要调用evtimer_add()函数。相反,需要调用evtimer_del()函数。

超时

除了简单的定时器,libevent可以为文件描述符指定一个超时事件,用于触发经过一段时间后而没有被激活的文件描述符执行相应的操作。timeout_set()函数可以为一个超时时间初始化一个事件结构。一旦被初始化成功,那么这个事件必须通过timeout_add()函数激活。为了取消一个超时事件,可以调用timeout_del()函数。

异步DNS解析

libevent提供了一个异步DNS解析器,可用于代替标准的DNS解析器。这些函数可以通过在程序中包含头文件而将其导入。在使用任何解析器函数之前,你必须调用evdns_init()函数初始化函数库。为转化一个域名到IP地址,可以调用evdns_resolve_ipv4()函数。为了执行一个反响查询,你可以调用evdns_resolve_reverse()函数。所有的这些函数,在查找时都会使用回调的方式而避免阻塞的发生。

事件驱动的HTTP服务器

libevent提供了一个简单的可以嵌入到你的程序中的并能处理HTTP请求的事件驱动HTTP服务器。为了使用这种能力,你应该在你的程序中包含头文件,你可以通过调用evhttp_new()函数来创建一个服务器。通过evhttp_bind_socket()函数添加用于监听的地址和端口。然后,你可以注册一个或多个对到来请求的处理句柄。对于每一个URI可以通过evhttp_set_cb()函数指定一个回调。通常一个回调函数也可以通过evhttp_set_gencb()函数完成注册;如果没有其他的回调已经被注册得到该URI,那么这个回调将会与其关联。

最新版本:2.0


官方主页:http://libevent.org/
该文章最后由 阿炯 于 2017-12-25 13:32:57 更新,目前是第 2 版。