深入Libevent源码
文章平均质量分 70
libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库。它有以下优点:高性能,轻量级,跨平台,支持多种 I/O 多路复用技术,支持 I/O,定时器和信号等事件,事件优先级。本专栏以libevent1.4.14源码为基础,一探它的究竟。
UKey_
勿以浮沙筑高台
展开
-
(十九)对libevent源码分析的总结
前言在写对libevent源码分析之前,其实已经阅读过几遍libevent源码,结果在分析的时候,还是遇到了一些障碍,不过还好都解决了。由于在真正意义上,这是我第一次分析超过万行的源码,所以可能在分析的过程中,有些遗漏难免发生,后面发现的时候再补上,如果有错误的地方,希望大家指出。总结libevent将定时事件、信号事件、I/O事件都集成到一起,并且可以支持多种多路I/O处理方法,采用了事件驱动机制原创 2017-09-04 09:36:00 · 1010 阅读 · 0 评论 -
(十八)bufferevent的读写回调函数及对外接口
前言在上一节中,我们介绍了bufferevent实现自动管理的基本思想(水位线机制),在本小节中,我们将介绍bufferevent_readcb、bufferevent_writecb等函数,了解它工作的全过程。bufferevent_readcbstatic voidbufferevent_readcb(int fd, short event, void *arg) { struct原创 2017-09-03 17:02:53 · 5729 阅读 · 1 评论 -
(十七)bufferevent的管理
前言在上节中,我们将evbuffers剩余的内容,比如读/写操作进行了剖析。接下来,我们将对bufferevent进行分析,它主要实现了对缓冲区的自动管理。 在本节中,我们先介绍相关结构体以及一些管理操作,相关代码在evbuffer.c以及event.h文件中。struct bufferevent该结构体用于管理bufferevent。定义如下:struct bufferevent { s原创 2017-09-03 15:21:28 · 983 阅读 · 0 评论 -
(十六)evbuffers缓冲区(下)
前言在上节中,我们介绍了evbuffers的部分知识,在本小节中,我们将对剩余的部分一起分析总结。evbuffer_drain在上节中分析的evbuffer_add_buffer中,如果添加源缓冲区到目的缓冲区结尾成功,则会调用evbuffer_drain清除源缓冲区,但是它的功能除了清除整个有效缓冲区以外,还可以清除一部分,接下来我们来看看它的源码:voidevbuffer_drain(stru原创 2017-09-02 15:05:57 · 1722 阅读 · 0 评论 -
(十五)evbuffers缓冲区(上)
前言evbuffer是libevent的缓冲区部分,它主要是负责缓冲区的构建等操作,而bufferevent主要负责管理输入输出缓冲区,相当于是对evbuffer做的一层抽象,缓冲区对于一个网络库几乎是必需的。我们来介绍关于evbuffer部分,部分主要集中在event.h和buffer.c。evbuffer结构体首先,先了解缓冲区的数据结构:struct evbuffer { u_原创 2017-09-01 19:44:58 · 1332 阅读 · 0 评论 -
(十四)支持多种IO多路复用的技术
前言众所周知,libevent支持多种I/O多路复用,如select、poll、epoll、kqueue等。那么其中是如何实现的呢? 主要就是结构体eventop,它内部成员有几个函数指针,统一了每种I/O多路复用的接口,也就是说,要想libevent支持某种I/O多路复用,就必须实现这几种接口。结构体eventop位于event-internal.h中。eventopstruct eventop原创 2017-08-31 22:03:41 · 778 阅读 · 0 评论 -
(十三)时间管理
前言在上一小节,我们主要介绍了定时事件相关的函数。在本小节中,为了加强这部分的理解,我们将探讨libevent有关时间管理的部分,比如我们之前在event_base_loop中看到的时间缓存,时间校正这些。初始化在event_base_new函数中有这样一段代码:detect_monotonic();gettime(base, &base->event_tv);min_原创 2017-08-31 22:00:37 · 649 阅读 · 0 评论 -
(十二)定时事件集成到多路IO机制
前言在本小节中,我们将展开对定时事件的研究。首先还是和研究信号事件部分一样,先看看它是如何集成到多路I/O中的(或者说是如何与event_base联系起来的)。如何将定时事件集成到主循环中由于seletc、poll、epoll这类多路I/O机制支持定时,所以将定时事件集成到主循环中比起信号事件容易的多。我们只需要将定时事件注册到小根堆上,然后根据堆顶(最短超时事件)来计算多路I/O机制需要等待的最大原创 2017-08-31 17:28:41 · 659 阅读 · 0 评论 -
(十一)信号事件的管理
前言在上一小节中我们主要讲解了信号事件是如何合并到多路I/O复用机制中的以及信号事件的初始化。在本小节中,我们将看到有关信号事件的主要操作。信号事件的注册前面我们看到了信号事件是在何时何地如何被初始化的,一个事件无非就是初始化、注册、激活、回调、注销这几个重要的操作。接下来我们看看信号事件注册相关的,即evsignal_add函数,它在signal.c文件中定义。intevsignal_add(s原创 2017-08-30 22:12:24 · 636 阅读 · 0 评论 -
(十)信号事件集成到多路I/O机制
前言之前剖析代码的时候我们知道事件没激活前,都有自己的数据结构来管理,但是在激活之后都是放在激活链表中的。本小节我们将介绍libevent中关于信号事件如何管理,如何将信号事件统一到多路I/O复用事件中一起管理的。如何将信号集成到主循环中libevent采用的是socket pair的方法。分为读socket和写socket,读socket会在event_base上注册一个读事件,而当信号发生时,记原创 2017-08-29 22:13:24 · 844 阅读 · 1 评论 -
(九)事件的激活与调度
前言我们在上一个小节中分析了事件主循环的整个过程以及event_base_once函数。可能信息量有点大,这一小节,我们把event.c剩下的一部分重要的函数分析分析。event_dispatch我们再回到讨论主循环这个话题来,在第1小节给的例子里面最后调用了event_dispatch,它其实干的就是事件主循环的事,只是做了几层封装而已。 下面我们来看一看。event_dispatchinte原创 2017-08-28 20:03:53 · 969 阅读 · 1 评论 -
(八)事件主循环
前言上一小节我们介绍了事件是如何注册/注销的,在本小节中,我们将进一步探讨事件从未注册到处理的整个过程,即事件的主循环。事件主循环事件的主循环主要是通过event_base_loop完成的。我们下面先来看看这个函数,再进行总结。event_base_loopintevent_base_loop(struct event_base *base, int flags){ const stru原创 2017-08-28 20:01:35 · 1155 阅读 · 1 评论 -
(七)注册/注销event事件
前言在本小节中,我们将看到event是如何注册到event_base上的,以及如何注销,如何激活等操作,最后还会梳理一下事件的状态是如何变化的。event_addintevent_add(struct event *ev, const struct timeval *tv){ struct event_base *base = ev->ev_base; const struct原创 2017-08-27 22:03:51 · 1581 阅读 · 0 评论 -
(六)初始化并设置event
## 前言 在这一小节里我们将接触到event.c源文件里面的一些关于设置event接口函数。这对我们了解event以及它和event_base之间的联系很有帮助。event_set首先我们看一看初始化event的操作:voidevent_set(struct event *ev, int fd, short events, void (*callback)(int, short,原创 2017-08-27 18:34:29 · 1017 阅读 · 0 评论 -
(五)struct event结构体
前言之前说到过libevent是基于事件驱动模型的网络库,其中的事件,就是event,它的确算是libevent中最核心的部分,而上一节说到的event_base其实算是驱动部分,负责事件的各种处理。它们之间的关系是,一个event_base对应多个event。 下面主要讲解的是struct event结构体,位于event.h。struct eventstruct event { /*原创 2017-08-26 20:41:47 · 2432 阅读 · 0 评论 -
(四)初探反应器(event_base)
前言在本节中,我们将初次接触struct event_base,并介绍下event_init函数。由于event_base属于整个libevent中中心的部位,所以我们没办法一下就完全弄懂它,需要结合后面的各部分知识才能有一个很好的认识。struct event_base还记得我们之前写的那个小例子吗,一开始调用了event_init()函数。它到底有什么作用?对应函数原型在libevent库中的e原创 2017-08-25 19:56:42 · 1141 阅读 · 0 评论 -
(三)libevent源文件结构
前言在正式阅读源码之前,我们先对libevent的整体结构有大致的了解。这对我们在大体上了解libevent很有好处。源文件结构进入到libevent库目录里面一看,好像还挺多的,不过除去脚本还有.lo与.la这些用libtool编译出来的目标文件以及库文件,也没剩多少了。主要分为事件头文件、内部头文件、事件主框架、对多种多路I/O复用的机制的封装、信号管理方面、定时事件管理方面、缓冲区管理方面、日原创 2017-08-26 14:08:28 · 881 阅读 · 0 评论 -
(二)什么是Reactor模式
Reactor模式(反应堆模式):这便是libevent的中心思想。在常规的I/O多路复用中采用select和poll、epoll等来实现,而将这些机制封装而成的就是I/O多路复用模式,Reactor就是其中之一。通俗的来讲,它就是通过回调机制实现的。我们只需将事件的接口注册到Reactor上,当事件发生之后,会回调注册的接口。比如你订闹钟明早六点半起床,那么在六点半之前你就可以安心睡觉,到了六点半原创 2017-08-25 19:49:01 · 2286 阅读 · 0 评论 -
(一)libevent安装及简单的使用
前言首先我阅读的版本是libevent-1.4.14b-stable版本。1.4系列虽然比较古老,但是它的源码相对简单,便于学习,并且主要的思想与2.0系列是一致的。 附上官网链接:http://libevent.org/安装及简单使用libevent接下来我们直接进入正题,安装libevent-1.4。 1. 在官网上下载对应版本的包 2. tar -zxvf /your path/libe原创 2017-08-25 19:46:54 · 14994 阅读 · 10 评论 -
(零)阅读源码的工具及参考资料
工具分析源码,首先对工具的准备很重要,在windows有阅读源码的利器source insight,但是由于我的日常系统是centos,并且不想在虚拟机下进行分析,所以找了一些linux阅读源码的工具。 我使用的主要工具是:ctags+cscope 接下来我简单介绍一下这些工具的使用ctags的使用在源码根目录执行ctags -R命令,递归的为源码建立tags,在根目录会生成一个Tags的文件,原创 2017-09-04 09:49:32 · 1711 阅读 · 0 评论