您的位置:首页 > 其它

libevent-0.1实现机制分析

2013-04-19 14:11 155 查看
libevent提供一种当特定事件发生、超时或信号到达时执行回调函数的机制,看了libevent的代码,里面包含了对普通事件、超时事件的处理;libevent-0.1(2000年发布)使用select来进行IO轮询,最新的libevent版本使用epoll。(http://monkey.org/~provos/libevent/

libevent的实现框架(三个主体 — 事件、队列、处理):

l 事件,每个事件由一个struct event标示;

struct event {

// 事件所处队列的链接指针

TAILQ_ENTRY (event) ev_read_next;

TAILQ_ENTRY (event) ev_write_next;

TAILQ_ENTRY (event) ev_timeout_next;

TAILQ_ENTRY (event) ev_add_next;

int ev_fd; // 与事件关联的文件描述符

short ev_events; // 事件类型

struct timeval ev_timeout; // 事件超时时间

void (*ev_callback)(int, short, void *arg); // 时间达到时的回调函数

void *ev_arg; // 回调函数的参数

int ev_flags; // 事件所在的队列标志

};

l 队列

libevent定义了四种类型的队列(tail queue)

TAILQ_HEAD (timeout_list, event) timequeue; // 超时队列

TAILQ_HEAD (event_wlist, event) writequeue; // 写等待队列

TAILQ_HEAD (event_rlist, event) readqueue; // 读等待队列

TAILQ_HEAD (event_ilist, event) addqueue; // 添加队列

其中,超时队列中包含有超时时间限制的事件;添加队列中的时间为需要延时加入的事件(在调用event_add时,正在进行事件派遣event_dispatch,这些事件要等本轮派遣结束才能加入)。

libevent提供了event_set接口来构造事件;event_add接口来往相应的队列中添加事件(同一个fd上的多个事件只需要构造一个event,并指明事件类型,event_add会将事件添加到相应的队列中); event_del来从响应的队列删除事件。

l 处理(派遣)

libevent提供event_dispatch接口来派遣等待的事件。event_dispatch首先遍历各个等待队列,将时间对应的描述符和事件类型加入select的fdset,然后选择超时时间最近的的事件(超时队列中的事件在插入时是按超时时间排序的,新的libevent使用堆),根据差值设置select的超时时间。select返回后,再次遍历各个队列中的事件,如果事件(或超时时间)已到达,则执行回调函数。处理完后,将addqueue中的事件加入到相应的队列中去,然后执行下一轮派遣处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: