- 浏览: 1400095 次
- 性别:
- 来自: 火星
文章分类
最新评论
-
aidd:
内核处理time_wait状态详解 -
ahtest:
赞一下~~
一个简单的ruby Metaprogram的例子 -
itiProCareer:
简直胡说八道,误人子弟啊。。。。谁告诉你 Ruby 1.9 ...
ruby中的类变量与类实例变量 -
dear531:
还得补充一句,惊群了之后,数据打印显示,只有一个子线程继续接受 ...
linux已经不存在惊群现象 -
dear531:
我用select试验了,用的ubuntu12.10,内核3.5 ...
linux已经不存在惊群现象
这里分析的是libevent-1.4.9。
PS:前面还看了libev的源代码,妈的,那代码写的太猥亵了,相比较libevent代码写的好多了。。
首先来看一下最主要的几个数据结构:
eventop结构体是所有事件驱动模型的基类。所有的io复用类型都会实现此结构体里各种方法。
event_base管理所有的event对象,它包含了一些全部变量,比如事件驱动引擎evsel等。所有的event对象都会包含这个结构体。
event结构表示每个事件,包含了一些事件私有的数据,比如回调函数等。。这里事件链表它使用了tail queue.
下面来介绍一下事件引擎中的两个结构,这里主要介绍下select,其他的几本类似.
selectop是全局的select数据结构,也就是上面event_base数据结构中evbase的值,我们通过avbase就可以操作select的数据结构
我们再来看下几个重要的函数(其中省略了一些语句,只介绍重要的一些语句):
event_init将event_base_new返回的值付给一个全局的变量current_base
event_add加一新的事件到当前事件引擎
loop函数将进入事件监测循环。
超时处理函数
这大过节的不去陪MM,还写代码?囧
呵呵!何必揭人家短,也可能是你以X人之心度君子之腹.
PS:前面还看了libev的源代码,妈的,那代码写的太猥亵了,相比较libevent代码写的好多了。。
首先来看一下最主要的几个数据结构:
eventop结构体是所有事件驱动模型的基类。所有的io复用类型都会实现此结构体里各种方法。
struct eventop { const char *name; ///<事件驱动名称 void *(*init)(struct event_base *); //<初始化 int (*add)(void *, struct event *); ///<加入新的事件监测 int (*del)(void *, struct event *); ///<从事件监测中删除某一事件 int (*dispatch)(struct event_base *, void *, struct timeval *);///<启动此事件监测 void (*dealloc)(struct event_base *, void *); ///<释放此事件驱动的资源 /* set if we need to reinitialize the event base */ int need_reinit; ///<标志位 };
event_base管理所有的event对象,它包含了一些全部变量,比如事件驱动引擎evsel等。所有的event对象都会包含这个结构体。
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; ///<这里libevent将定时器队列实现为一个最小堆,也就是为了每次都把时间最晚的定时器能取出来,然后实现超时。更其实算法很简单,想要详细的了解可以去看下算法导论的第六章的Priority queues. struct timeval tv_cache; };
event结构表示每个事件,包含了一些事件私有的数据,比如回调函数等。。这里事件链表它使用了tail queue.
struct event { TAILQ_ENTRY (event) ev_next; ///<下一个事件 TAILQ_ENTRY (event) ev_active_next; ///<下一个激活事件 TAILQ_ENTRY (event) ev_signal_next; ///<下一个信号事件列表 unsigned int min_heap_idx; /* for managing timeouts */ struct event_base *ev_base; ///<全局的base int ev_fd; ///<所需要监测的事件句柄 short ev_events; short ev_ncalls; short *ev_pncalls; /* Allows deletes in callback */ struct timeval ev_timeout; ///<超时时间 int ev_pri; /* smaller numbers are higher priority */ void (*ev_callback)(int, short, void *arg); ///<回调函数 void *ev_arg; ///<传递给回调函数的参数 int ev_res; /* result passed to event callback */ int ev_flags; };
下面来介绍一下事件引擎中的两个结构,这里主要介绍下select,其他的几本类似.
selectop是全局的select数据结构,也就是上面event_base数据结构中evbase的值,我们通过avbase就可以操作select的数据结构
struct selectop { int event_fds; /* Highest fd in fd set */ int event_fdsz; fd_set *event_readset_in; fd_set *event_writeset_in; fd_set *event_readset_out; fd_set *event_writeset_out; struct event **event_r_by_fd; struct event **event_w_by_fd; }; selectops也就是实现了eventop。它导出了select的接口。 const struct eventop selectops = { "select", select_init, select_add, select_del, select_dispatch, select_dealloc, 0 };
我们再来看下几个重要的函数(其中省略了一些语句,只介绍重要的一些语句):
struct event_base * event_base_new(void) { ...................................... //前面就是一些初始化,最重要的部分是下面的这个for循环。在这里初始化事件驱动引擎。这里eventops是一个eventop数组,里面包含所有事件驱动引擎的接口(就像上面介绍的selectops结构) for (i = 0; eventops[i] && !base->evbase; i++) { base->evsel = eventops[i]; ///下面调用初始化函数,返回每个事件引擎的全局数据结构 base->evbase = base->evsel->init(base); } .................................. /* allocate a single active event queue */ event_base_priority_init(base, 1); return (base); }
event_init将event_base_new返回的值付给一个全局的变量current_base
struct event_base * event_init(void) { struct event_base *base = event_base_new(); if (base != NULL) current_base = base; return (base); }
event_add加一新的事件到当前事件引擎
int event_add(struct event *ev, const struct timeval *tv) { ///取得当前事件的一些有用的数据结构。 struct event_base *base = ev->ev_base; const struct eventop *evsel = base->evsel; void *evbase = base->evbase; int res = 0; /* * prepare for timeout insertion further below, if we get a * failure on any step, we should not change any state. */ if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) { if (min_heap_reserve(&base->timeheap, 1 + min_heap_size(&base->timeheap)) == -1) return (-1); /* ENOMEM == errno */ } ///这里调用evsel->add来加一事件到当前的事件引擎。 if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) && !(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) { res = evsel->add(evbase, ev); if (res != -1) event_queue_insert(base, ev, EVLIST_INSERTED); } /* * we should change the timout state only if the previous event * addition succeeded. */ if (res != -1 && tv != NULL) { struct timeval now; /* * we already reserved memory above for the case where we * are not replacing an exisiting timeout. */ //如果超时就先删除此事件。 if (ev->ev_flags & EVLIST_TIMEOUT) event_queue_remove(base, ev, EVLIST_TIMEOUT); /* Check if it is active due to a timeout. Rescheduling * this timeout before the callback can be executed * removes it from the active list. */ if ((ev->ev_flags & EVLIST_ACTIVE) && (ev->ev_res & EV_TIMEOUT)) { /* See if we are just active executing this * event in a loop */ if (ev->ev_ncalls && ev->ev_pncalls) { /* Abort loop */ *ev->ev_pncalls = 0; } event_queue_remove(base, ev, EVLIST_ACTIVE); } gettime(base, &now); //计算超时时间并赋值给ev_timeout evutil_timeradd(&now, tv, &ev->ev_timeout); event_debug(( "event_add: timeout in %ld seconds, call %p", tv->tv_sec, ev->ev_callback)); //将此定时器加入定时器最小堆。 event_queue_insert(base, ev, EVLIST_TIMEOUT); } return (res); }
loop函数将进入事件监测循环。
int event_base_loop(struct event_base *base, int flags) { ............................................ ....................................... ///校准时间,非Monotonic时钟这个函数将会立即返回。 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); } /* If we have no events, we just exit */ if (!event_haveevents(base)) { event_debug(("%s: no events registered.", __func__)); return (1); } /* update last old time */ gettime(base, &base->event_tv); /* clear time cache */ base->tv_cache.tv_sec = 0; ///调用相应的事件引擎处理函数 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; } .................................................. }
超时处理函数
void timeout_process(struct event_base *base) { struct timeval now; struct event *ev; if (min_heap_empty(&base->timeheap)) return; gettime(base, &now); ///遍历定时器 while ((ev = min_heap_top(&base->timeheap))) { if (evutil_timercmp(&ev->ev_timeout, &now, >)) break; /* delete this event from the I/O queues */ event_del(ev); event_debug(("timeout_process: call %p", ev->ev_callback)); ///激活此事件 event_active(ev, EV_TIMEOUT, 1); } }
评论
3 楼
shaibiao
2009-02-17
笨笨狗 写道
这大过节的不去陪MM,还写代码?囧
呵呵!何必揭人家短,也可能是你以X人之心度君子之腹.
2 楼
笨笨狗
2009-02-16
这大过节的不去陪MM,还写代码?囧
1 楼
climber2002
2009-02-15
猥亵这个词用得很传神
发表评论
-
gcc的几个自动优化
2009-11-10 00:44 5142我的gcc版本是4.4.1 先来看const和define以 ... -
gdb学习笔记(一)
2009-10-17 14:11 11730这里只是一个摘要。具体的细节还需要去看manual。 1 ... -
ydb的内存模型
2009-09-06 18:02 1978阿宝同学推荐了这个东 ... -
glibc中strlen的实现
2009-08-04 09:10 4526glibc中的strlen的实现主要的思想就是每次检测4个字节 ... -
libevent源码浅析(四)
2009-05-15 23:02 4426最近刚刚一个项目自己用libevent,因此这几天又把libe ... -
libevent源码浅析(三)
2009-03-17 00:08 4582这次我们来看libevent的信号的处理。 在libeven ... -
libevent源码浅析(二)
2009-02-22 00:11 4075我们来看下libevent的定时器的实现 在libevent ... -
linux下的time处理
2009-01-04 18:02 6842在内核中有3个不同的时间: Wall time(real t ... -
libev简单使用介绍
2008-12-30 09:52 11548更详细的用法请看他的 ... -
linux下的elf结构
2008-12-12 00:20 5186可以看到链接器和加载器看待elf是完全不同的,链接器看到 ... -
php的c扩展
2008-12-07 18:24 4570在php中最核心的一个数据结构就是这个: typedef u ... -
linux下的管理内存相关的函数
2008-11-27 00:56 4484malloc的实现,在linux下的实现是这样的,当所需 ... -
linux下的数据对齐
2008-11-25 12:15 3647数据对齐也就是通过硬件来估算在数据的地址和内存块之间的联系。当 ... -
linux下检测ip冲突
2008-11-16 20:18 8173原理其实很简单,那就是广播一个arp包,然后recv,如果没有 ... -
今天碰到的一个问题
2008-10-29 22:33 1264将位图用 bmptopnm 转成pcl6的打印语言,然后直接c ... -
ftruncate和msync
2008-10-23 22:10 3498int ftruncate(int fd, off_t le ... -
GUN C正则表达式
2008-09-25 23:47 6192最近项目中要处理文本,因此就用了gun的正则表达式,它是pos ... -
看代码看的头晕
2008-09-06 01:04 1867最近工作需要在看ghostscript的代码,看得我头晕眼花, ... -
[转帖]MISRA--作为工业标准的C编程规范
2008-08-21 13:19 2834本文档转贴自孟岩的blog ... -
代码大全读书笔记1
2008-04-26 19:16 3823这么好的书,觉得写点东西,记录一下比较好。 4.1选择编程语 ...
相关推荐
为方便阅读,把blog上的libevent源码深度剖析系列文章整合成一个pdf。
本文将对libevent源码进行分析,深入理解其实现原理以及关键的数据结构和函数接口。我们首先从libevent源码的整体架构开始,然后详细介绍一些重要的组件和它们的实现方式。 1. 开篇 在分析libevent源码之前,有必要...
Libevent是一款高性能的事件通知库,最初由Nick Mathewson和George V. Reilly开发,广泛应用于需要处理多个事件源的网络编程中。该库支持多种操作系统,为跨平台编程提供便利,例如在Linux、BSD、Mac OS X以及...
libevent库,文字版,很清晰,附带libevent参考手册(中文版) libevent源码深度剖析,根据libevent开源代码框架进行剖析,很不错值得学习借鉴,还有libevent中C语言的功底值得学习揣摩!
Libevent 源码解析 Libevent 是一个高性能的事件驱动库,广泛应用于网络编程和高性能服务器开发中。下面是对 Libevent 源码的深入剖析,涵盖了其架构设计、事件处理机制、Reactor 模式、事件循环、IO multiplexing...
libevent源码深度剖析
《libevent参考手册(中文版)》和《libevent源码深度剖析》是两本针对libevent库的重要参考资料。libevent是一个开源的事件通知库,它使得开发者能够编写高性能、可扩展的网络服务器或者客户端应用。这个库的核心...
《libevent源码深度剖析》 libevent是一个高度优化的事件通知库,广泛应用于网络编程,尤其是服务器端的高性能设计。它提供了一种抽象层,允许程序员以一致的方式处理各种类型的事件,包括文件描述符(如套接字)的...
标题"libevent 参考手册中文版及源码解析"表明了本次学习的主题,重点是libevent库,包含了中文参考手册和源码的深度解析。libevent是一个开源的事件通知库,它使开发者能够方便地处理各种网络事件,如TCP、UDP、...
**libevent库源码详解** libevent是一个高度可移植、事件驱动的网络库,它能够帮助程序员处理大量的并发连接,并且有效地利用系统资源。在2.1.8stable版本中,libevent提供了丰富的功能和优化,使其成为开发高性能...
`libevent-2.1.8-stable.tar.gz`是Libevent的一个稳定版本源码包,用户可以编译安装来使用其提供的API来编写网络服务器、客户端或者其他需要高效处理I/O事件的程序。 在使用这些源码时,开发者需要有一定的C语言...
标题"libevent源码和一个小例子"指的是一个关于libevent库的源代码分析以及如何使用它的具体示例。Libevent是一个事件通知库,它用于编写高性能的网络服务器,处理TCP、UDP、HTTP、SSL和其他IO事件。在给定的描述中...
libevent 源码深度剖析.pdf libevent 源码 深度 剖析 pdf
Libevent 是一个高度优化的事件通知库,广泛用于编写高性能的网络服务器和客户端程序。...这个“Libevent源码和资料合集”正是这样一个宝贵的资源,它包含的源代码和相关资料将帮助你全面掌握Libevent的精髓。
《libevent源码分析1》 在深入探讨libevent的源码之前,我们先来了解一下这个库的基本情况。libevent是一个高度可扩展的事件通知库,它用于编写高性能、高并发的网络服务器。它的核心功能是提供了一种高效的方式来...