libevent-0.1实现机制分析

libevent提供一种当特定事件发生、超时或信号到达时执行回调函数的机制,看了libevent的代码,里面包含了对普通事件、超时事件的处理;libevent-0.12000年发布)使用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首先遍历各个等待队列,将时间对应的描述符和事件类型加入selectfdset,然后选择超时时间最近的的事件(超时队列中的事件在插入时是按超时时间排序的,新的libevent使用堆),根据差值设置select的超时时间。select返回后,再次遍历各个队列中的事件,如果事件(或超时时间)已到达,则执行回调函数。处理完后,将addqueue中的事件加入到相应的队列中去,然后执行下一轮派遣处理。

 

posted @ 2013-04-19 14:11  ydzhang  阅读(412)  评论(0编辑  收藏  举报