学习libevent有助于提升程序设计功力,除了网络程序设计方面外,libevent的代码里有很多有用的设计技巧和基础数据结构,比如信息隐藏、函数指针、c语言的多态支持、链表和堆等等,都有助于提升自身的程序功力。
       程序设计不止要了解框架,很多细节之处恰恰也是事关整个系统成败的关键。只对libevent本身的框架大概了解,那或许仅仅是一知半解,不深入代码分析,就难以了解其设计的精巧之处,也就难以为自己所用。
       事实上libevent本身就是一个典型的Reactor模型,理解Reactor模式是理解libevent的基石。因此本篇将介绍典型的事件驱动设计模式——Reactor模式,并列出libevnet中的几个重要组件和Reactor的对应关系。
1 Reactor的事件处理机制
       首先来回想一下普通函数调用的机制:程序调用某函数?函数执行,程序等待?函数将结果和控制权返回给程序?程序继续处理。
       Reactor释义“反应堆”,是一种事件驱动机制。和普通函数调用的不同之处在于:应用程序不是主动的调用某个API完成处理,而是恰恰相反,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,如果相应的事件发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”。使用libevent也就是向libevent框架注册相应的事件和回调函数;当这些事件发声时,libevent会调用这些回调函数处理相应的事件(I/O读写、定时和信号)。
       用“好莱坞原则”来形容Reactor再合适不过了:不要打电话给我们,我们会打电话通知你。
举个例子:你去应聘某xx公司,面试结束后。
       “普通函数调用机制”公司HR比较懒,不会记你的联系方式,那怎么办呢,你只能面试完后自己打电话去问结果;有没有被录取啊,还是被据了;
       “Reactor”公司HR就记下了你的联系方式,结果出来后会主动打电话通知你:有没有被录取啊,还是被据了;你不用自己打电话去问结果,事实上也不能,你没有HR的留联系方式。
2 Reactor模式的优点
        Reactor模式是编写高性能网络服务器的必备技术之一,它具有如下的优点:
1)响应快,不必为单个同步事件所阻塞,虽然Reactor本身依然是同步的;
2)编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销;
3)可扩展性,可以方便的通过增加Reactor实例个数来充分利用CPU资源;
4)可复用性,reactor框架本身与具体事件处理逻辑无关,具有很高的复用性。

3 Reactor模式框架

使用Reactor模型,必备的几个组件:事件源、Reactor框架、多路复用机制和事件处理程序,先来看看Reactor模型的整体框架,接下来再对每个组件做逐一说明。

1)handle——事件源
Linux上是文件描述符,Windows上就是Socket或者Handle了,这里统一称为“句柄集”;程序在指定的句柄上注册关心的事件,在libevent中有三种类型的事件:定时器事件(time event)、信号事件(signal event)和I/O事件。

2)event demultiplexer——事件多路分发机制
由操作系统提供的I/O多路复用机制,比如select和epoll。程序首先将其关心的句柄(事件源)及其事件注册到event demultiplexer上;当有事件到达时,event demultiplexer会发出通知事件处理程序“在已经注册的句柄集中,一个或多个句柄的事件已经就绪”;程序收到通知后,就可以在非阻塞的情况下对事件进行处理了。
对应到libevent中,依然是select、poll、epoll等,但是libevent使用结构体eventop进行了封装,以统一的接口来支持这些I/O多路复用机制,达到了对外隐藏底层系统机制的目的

3)Reactor——反应器
Reactor,是事件管理的接口,内部使用event demultiplexer注册、注销事件;并运行事件循环,当有事件进入“就绪”状态时,调用注册事件的回调函数处理事件。对应到libevent中,就是event_base结构体。

4)Event Handler——事件处理程序
事件处理程序提供了一组接口,每个接口对应了一种类型的事件,供Reactor在相应的事件发生时调用,执行相应的事件处理。通常它会绑定一个有效的句柄。对应到libevent中,就是event结构体。

4 Reactor事件处理流程

在高性能服务器并发模型设计中,Reactor和Proactor是两个经常用到的设计模式,前者用于同步IO,后者用于异步IO,前者在IO操作 就绪的情况下通知用户,用户再采取实际的IO操作,后者是在IO操作完成后通知用户。

IOCP的设计就是Proactor 模式的完美体现,而epoll则很容易实现Reactor模式,asio设计为跨平台,并且在linux下采用epoll,我的印象中linux对异步 IO的支持没有windows那么完善(看看IOCP和epoll模型的区别就知道),那么asio是怎么用epoll机制实现proactor模式的 呢,刚开始想的是应该在应用层做了一层封装,就是asio内部应该有某个循环调用epoll_wait,当有IO事件就绪时帮用户做一些操作(比如把数据 拷贝到我们提交的缓冲区),然后在操作完成的时候调用我们的handler(后来看代码基本是这样).OK,不说废话了.

本质上来讲libevent应该是同步的,因为如果看到底层封装的select和epoll就会发现,里面仍然是个while循环,在不停的询问,是否准备就绪,
而异步同步IO的主要区别就是,应用发起一个 IO 操作以后,不等待内核 IO 操作的完成,等内核完成 IO 操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问 IO 是否完成,显然select和epoll是同步的。
另外本身Reactor模式就是同步的模式不是吗?

如果你理解底层的select或者epoll。你会发现它其实是同步的。有一个while循环,等待事件触发条件。满足条件则调用相应的callback函数。因此本质上还是同步的。不过长了一个异步的脸

libevent本身是一个Reactor,是同步的。但libevent的bufferevent是用Reactor实现了一个Proactor,所以libevent又是异步的

reactor模型框架图和流程图 libevent的更多相关文章

  1. gentoo 画框架图,流程图

    需要话框架图,流程图的时候,只需要安装 dia 软件就可以了.

  2. [转][osg]osg渲染引擎框架图,流程图(根据《最长一帧》整理)

    转自:http://m.blog.csdn.net/article/details?id=49679731 本文参考<<osg最长一帧>>, <<OpenScene ...

  3. 框架篇:见识一下linux高性能网络IO+Reactor模型

    前言 网络I/O,可以理解为网络上的数据流.通常我们会基于socket与远端建立一条TCP或者UDP通道,然后进行读写.单个socket时,使用一个线程即可高效处理:然而如果是10K个socket连接 ...

  4. Reactor模型

    Reactor模型 原文地址:http://www.ivaneye.com/2016/07/23/iomodel.html 无处不在的C/S架构 在这个充斥着云的时代,我们使用的软件可以说99%都是C ...

  5. Redis 源码简洁剖析 09 - Reactor 模型

    Reactor 模型 事件驱动框架 Redis 如何实现 Reactor 模型 事件的数据结构:aeFileEvent 主循环:aeMain 函数 事件捕获与分发:aeProcessEvents 函数 ...

  6. SpringMVC框架图解析

    Spring框架提供了构造Web应用程序的全能MVC模块.Spring MVC分离了控制器.模型对象.分派器以及处理程序对象的角色,这种分离让它们更容易进行制定.是一个标准的MVC框架. 那你猜一猜哪 ...

  7. 【转】各种图(流程图,思维导图,UML,拓扑图,ER图)简介

    原文地址:各种图(流程图,思维导图,UML,拓扑图,ER图)简介 流程图 1.定义:流程图是对过程.算法.流程的一种图像表示,在技术设计.交流及商业简报等领域有广泛的应用. 2.案例 3.计算机语言只 ...

  8. iOS学习——iOS 整体框架及类继承框架图

    整理自:IOS 整体框架类图值得收藏 一 整体框架 在iOS开发过程中,对iOS的整理框架的了解和学习是必不可少的一个环节,今天我们就好好来了解一下iOS的整体框架.首先贴一个关于iOS的框架介绍:i ...

  9. 强大的 10款 Mac 思维导图和流程图软件推荐

    本文首发于[风云社区 SCOEE],想了解更多mac软件相关内容,可到[风云社区 SCOEE] 今天和大家分享思维导图和流程图工具,思维导图软件可以说应用非常的广,无论是设计工作.开发工作.管理工作都 ...

随机推荐

  1. mysql中Access denied for user 'root'@'localhost' (using password:YES)错误

    此错误主要是由于你的系统曾经装过MYSQL,在重装就会要求输入原来设定的密码    由于输入错误导致    解决办法见 上一篇博客   MYSQL安装时解决要输入current root passwo ...

  2. [Redis] redis数据备份恢复与持久化

    数据库备份,使用save命令,将会在redis的安装目录中生成dump.rdb 例如:在我的目录下 redis/src/dump.rdb 使用命令config get dir,获取当前redis的安装 ...

  3. iOS 关于Xcode上的Other linker flags

    Targets选项下有Other linker flags的设置,用来填写XCode的链接器参数,如:-ObjC -all_load -force_load等.还记得我们在学习C程序的时候,从C代码到 ...

  4. 【转】SpringBoot系列之—瘦身部署

    一.前言 SpringBoot部署起来虽然简单,如果服务器部署在公司内网,速度还行,但是如果部署在公网(阿里云等云服务器上),部署起来实在头疼: 编译出来的 Jar 包很大,如果工程引入了许多开源组件 ...

  5. Unix Programming :文件IO

    文件描述符常量(unistd.h): STDIN_FILENO STDOUT_FILENO STDERR_FILENO 通常这些常量分别对应于数字0,1,2 文件操作需要头文件 fcntl.h ,一些 ...

  6. SQL SERVER DATETIME应用

    ),, , ),); ),, ),); ),, , ),); ),, ),); ),, , ),); ),, ),); How to get first and last day of previou ...

  7. Oracle数据库函数总结

    1.ceil()向上取整,结果为124.select ceil(123.123) from dual;2.floor()向下取整,结果为123.select floor(123.123) from d ...

  8. pipenv虚拟环境和依赖管理工具

    一.pipenv用来干嘛 每门编程语言发展到现在,都需要一个工具,能够管理代码版本和控制生产环境和测试环境依赖一致的,这样减少不可代码上线之后不可控的问题出现.Php有Composer.Nodejs有 ...

  9. Qt编译目录下exe文件执行报错问题的解决办法

    使用Qt5.9.3+vs2017环境,编译项目生成Debug目录,运行其中的exe文件,出现以下错误(qt creator调试状态下或出安装包后是可以运行的): 经过查阅资料,发现是我重新配置Qt开发 ...

  10. Windows win7下VMware Virtual Ethernet Adapter未识别网络解决方法

    win7下VMware Virtual Ethernet Adapter未识别网络解决方法[摘] by:授客 QQ:1033553122 问题描述 win7系统下安装VMware,查看网卡适配器设置, ...