chromium android/linux/mac 中用libevent来做为底层io检测,即MessagePumpLibevent来实现io线程循环。
1 libevent 简介(百度百科)
官网: http://libevent.org/
libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。libevent支持多线程编程,每个事件需要关联到自己的event_base。libevent包括事件管理、缓存管理、DNS、HTTP、缓存事件几大部分。事件管理包括各种IO(socket)、定时器、信号等事件;缓存管理是指evbuffer功能;DNS是libevent提供的一个异步DNS查询功能;HTTP是libevent的一个轻量级http实现,包括服务器和客户端。libevent也支持ssl,这对于有安全需求的网络程序非常的重要,但是其支持不是很完善,比如http server的实现就不支持ssl。
2. libevent 简单使用
http://www.open-open.com/lib/view/open1386510630330.html
1> timer事件
<span style="font-size:12px;">#include <stdio.h> #include <iostream> // libevent头文件 #include <event.h> using namespace std; // 定时事件回调函数 void onTime(int sock, short event, void *arg) { cout << "Game Over!" << endl; struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; // 重新添加定时事件(定时事件触发后默认自动删除) event_add((struct event*)arg, &tv); } int main() { // 初始化 event_init(); struct event evTime; // 设置定时事件 evtimer_set(&evTime, onTime, &evTime); struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; // 添加定时事件 event_add(&evTime, &tv); // 事件循环 event_dispatch(); return 0; } </span>2> io端口监听
伪代码
<span style="font-size:12px;">int main(void) { // 初始化base base = event_base_new(); struct event evListen; // 设置事件 event_set(&evListen, fd, EV_READ|EV_PERSIST, CallbackFunction, NULL); // 设置为base事件 event_base_set(base, &evListen); // 添加事件 event_add(&evListen, NULL); // 事件循环 event_base_dispatch(base); return 0; } </span>
3. libevent 事件循环
上述例子中,调用event_base_dispatch函数就进入了libevent事件循环,但真正的循环函数是event_base_loop。event_base_dispatch调用event_base_loop,其中flags参数为0.
int event_base_loop(struct event_base *base, int flags);
该函数可以工作在3中模式下,有flags来区分不同的模式。libevent中定义了两个宏来区别循环模式:
#define EVLOOP_ONCE 0x01
#define EVLOOP_NONBLOCK 0x02
默认情况下,event_base_loop()函数运行event_base直到其中没有已经注册的事件为止。执行循环的时候,函数重复地检查(多种 I/O多路复用技术: epoll、poll、dev/poll、select 和kqueue )是否有任何已经注册的事件被触发(比如说,读事件的文件描述符已经就绪,可以读取了;或者超时事件的超时时间即将到达)。如果有事件被触发,函数标记被触发的事件为“激活的”,并且执行这些事件。
如果设置了EVLOOP_ONCE,循环将等待某些事件成为激活的,执行激活的事件直到没有更多的事件可以执行,然会返回。
如果设置了EVLOOP_NONBLOCK,循环不会等待事件被触发:循环将仅仅检测是否有事件已经就绪,可以立即触发,如果有,则执行事件的回调。
chromium中使用了`EVLOOP_ONCE和EVLOOP_NONBLOCK
4. 多路复用封装eventop
struct eventop {
};
epoll、poll、dev/poll、select 和kqueue 都会实现这5个接口。
资料:
http://blog.csdn.net/sparkliang/article/details/4957667
http://www.cppblog.com/mysileng/archive/2013/02/04/197719.html