快速业务通道

libevent源码浅析(四)

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29

最近刚刚一个项目自己用libevent,因此这几天又把libevent的代码拿出来翻了下,当初看的时候有些似是而非的东西,这次是基本没有了。这篇也算是前面几篇libevent的blog的补充了。

struct event_base {
 const struct eventop *evsel;
 void *evbase;
 int event_count; /* counts number of total events */
 int event_count_active; /* counts number of active events */

 int event_gotterm; /* Set to terminate loop */
 int event_break; /* Set to terminate loop immediately */

 /* active event management */
 struct event_list **activequeues;
 int nactivequeues;

 /* signal handling info */
 struct evsignal_info sig;

 struct event_list eventqueue;
 struct timeval event_tv;

 struct min_heap timeheap;

 struct timeval tv_cache;
};

我们这里用select来讲,其他的事件驱动器都相似。

我们来看,其中activequeues我们知道是表示激活的事件队列.这里libevent的处理是,select被唤醒后,调用 event_active方法,将此事件插入到activequeues队列中,这里这个队列的实现是用tail queue。然后libevent会执行event_process_active方法,从而从激活队列中,依次执行所激活的事件。这里这个队列之所以是一个指针的指针,是因为,libevent中事件还分为优先级,这样每个优先级都有一个activequeues队列。

记下来我们再来看定时器的实现,libevent会在每次执行循环时,从优先级队列中取出来最小的那个时间,然后将它加入到select中,从而实现定时器。而在每次select超时退出后,libevent会从小到大取出超时时间(直到大于当前时间),每次和当前时间比较,如果已超时,则会从优先级队列中删除此节点,然后将此超时事件加入到激活队列中。

接下来我们来看相关代码。

int
event_base_loop(struct event_base *base, int flags)
{
..................................................

 timeout_correct(base, &tv);

 tv_p = &tv;
///判断是否有激活事件,如果没有的话我们则会从优先级队列中取出最小的那个时间。也就是离现在最近的那个超时时间。
 if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK)) {
///下面会介绍这个函数
  timeout_next(base, &tv_p);
 } else {
  /*
  * if we have active events, we just poll new events
  * without waiting.
  */
  evutil_timerclear(&tv);
 }

.........................................................
 /* clear time cache */
 base->tv_cache.tv_sec = 0;
///调用相关事件驱动引擎的dispatch方法,这个方法中会将已激活的事件加入到激活队列,这里看到tv_p也就是上面取到的超时时间被传入到dispatch。
 res = evsel->dispatch(base, evbase, tv_p);

 if (res == -1)
  return (-1);
 gettime(base, &base->tv_cache);
///处理超时事件,将所有已超时的事件加入到激活队列。下面我们会介绍这个函数
 timeout_process(base);

 if (base->event_count_active) {
 ///执行激活事件队列
  event_process_active(base);
  if (!base->event_count_active && (flags & EVLOOP_ONCE))
///判断是否退出。
  done = 1;
 } else if (flags & EVLOOP_NONBLOCK)
  done = 1;
 }

 /* clear time cache */
 base->tv_cache.tv_sec = 0;
 event_debug(("%s: asked to terminate 

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号