关于Reactor和Proactor的差别
/*********************************************************************
* Author : Samson
* Date : 07/12/2015
* Test platform:
* gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
* GNU bash, 4.3.11(1)-release (x86_64-pc-linux-gnu)
* Nginx version:
* Nginx 1.6.2
* Nginx 1.8.0
* *******************************************************************/
系统I/O 可分为堵塞型。 非堵塞同步型以及非堵塞异步型。
堵塞型I/O意味着控制权仅仅到调用操作结束了才会回到调用者手里。
非堵塞同步是会马上返回控制权给调用者的。
调用者不须要等等。它从调用的函数获取两种结果:要么此次调用成功进行了;要么系统返回错误标识告诉调用者当前资源不可用,你再等等或者再试度看吧。比方read()操作。 假设当前socket无数据可读,则马上返回EWOULBLOCK/EAGAIN,告诉调用read()者”数据还没准备好,你稍后再试”。
非堵塞异步调用中,稍有不同。调用函数在马上返回时,还告诉调用者。这次请求已经開始了。系统会使用另外的资源或者线程来完毕这次调用操作。并在完毕的时候知会调用者(比方通过回调函数)。POSIX的aio_read()来说。调用它之后,函数马上返回,操作系统在后台同一时候開始读操作。即是将工作交给了内核去完毕这个操作。
在以上三种IO形式中。非堵塞异步是性能最高、伸缩性最好的。
两种IO多路复用方案:Reactor and Proactor
普通情况下,I/O 复用机制须要事件分享器(event demultiplexor)。 事件分享器的作用,即将那些读写事件源分发给各读写事件的处理者。就像送快递的在楼下喊: 谁的什么东西送了, 快来拿吧。
开发者在開始的时候须要在分享器那里注冊感兴趣的事件。并提供对应的处理者(event handlers),或者是回调函数; 事件分享器在适当的时候会将请求的事件分发给这些handler或者回调函数。
涉及到事件分享器的两种模式称为:Reactor and Proactor。 Reactor模式是基于同步I/O的,而Proactor模式是和异步I/O相关的。
在Reactor模式中,事件分离者等待某个事件或者可应用或个操作的状态发生(比方文件描写叙述符可读写。或者是socket可读写),事件分离者就把这个事件传给事先注冊的事件处理函数或者回调函数,由后者来做实际的读写操作。
而在Proactor模式中。事件处理者(或者代由事件分离者发起)直接发起一个异步读写操作(相当于请求),而实际的工作是由操作系统来完毕的。发起时。须要提供的參数包含用于存放读到数据的缓存区,读的数据大小,或者用于存放外发数据的缓存区,以及这个请求完后的回调函数等信息。事件分离者得知了这个请求,它默默等待这个请求的完毕,然后转发完毕事件给对应的事件处理者或者回调。
这样的异步模式的典型实现是基于操作系统底层异步API的。所以我们可称之为“系统级别”的或者“真正意义上”的异步。由于详细的读写是由操作系统代劳的。
举另外个样例来更好地理解Reactor与Proactor两种模式的差别。这里我们仅仅关注read操作。由于write操作也是差点儿相同的。
以下是Reactor的做法:
某个事件处理者宣称它对某个socket上的读事件非常感兴趣;
事件分离者等着这个事件的发生;
当事件发生了,事件分离器被唤醒,这负责通知先前那个事件处理者;
事件处理者收到消息,于是去那个socket上读数据了。 假设须要,它再次宣称对这个socket上的读事件感兴趣,一直反复上面的步骤;
以下再来看看真正意义的异步模式Proactor是怎样做的:
事件处理者直接投递发一个写操作(当然,操作系统必须支持这个异步操作)。 这个时候。事件处理者根本不关心读事件,它仅仅管发这么个请求,它魂牵梦萦的是这个写操作的完毕事件。
这个处理者非常拽,发个命令就无论详细的事情了。仅仅等着别人(系统)帮他搞定的时候给他回个话。
事件分离者等着这个读事件的完毕(比較下与Reactor的不同);
当事件分离者默默等待完毕事情到来的同一时候,操作系统已经在一边開始干活了,它从目标读取数据,放入用户提供的缓存区中。最后通知事件分离者,这个事情我搞完了;
事件分享者通知之前的事件处理者: 你吩咐的事情搞定了;
事件处理者这时会发现想要读的数据已经乖乖地放在他提供的缓存区中,想怎么处理都行了。假设有须要。事件处理者还像之前一样发起另外一个写操作,和上面的几个步骤一样。
标准的经典的 Reactor模式:
步骤 1) 等待事件 (Reactor 的工作)
步骤 2) 发”已经可读”事件发给事先注冊的事件处理者或者回调 ( Reactor 要做的)
步骤 3) 读数据 (用户代码要做的)
步骤 4) 处理数据 (用户代码要做的)
模拟的Proactor模式:
步骤 1) 等待事件 (Proactor 的工作)
步骤 2) 读数据(看。这里变成成了让 Proactor 做这个事情)
步骤 3) 把数据已经准备好的消息给用户处理函数,即事件处理者(Proactor 要做的)
步骤 4) 处理数据 (用户代码要做的)
在没有底层异步I/O API支持的操作系统。这样的方法能够帮我们隐藏掉socket接口的差异(不管是性能还是其他)。 提供一个全然可用的统一“异步接口”。这样我们就能够开发真正平台独立的通用接口了。
那么,综上所述,这两者的差别是什么呢?
简单直观的理解:
1、Reactor模式是等待关心的动作的发生后。将怎样处理这个动作的兴许交给了用户态的应用本身来处理。Reactor的事件分享器仅仅关心事件的发生。其他的就全然交给应用程序来处理了;而Proactor模式则是仅仅关心由操作系统(内核)完毕异步非堵塞的操作后返回的结果。
2、Proactor场景中仅仅可以使用异步非堵塞的syscall(系统调用)。而Reactor的场景中很多其它地是使用非堵塞同步的syscall(系统调用);
对于不明确
IO - 同步,异步,堵塞,非堵塞概念的请先看下这个科普:
http://blog.csdn.net/historyasamirror/article/details/5778378
REF:
关于Reactor和Proactor的差别的更多相关文章
- 【转】Reactor与Proactor两种模式区别
转自:http://www.cnblogs.com/cbscan/articles/2107494.html 两种IO多路复用方案:Reactor and Proactor 一般情况下,I/O 复用机 ...
- 【Network】一张图看懂 Reactor 与 Proactor 模型的区别
首先来看看Reactor模式,Reactor模式应用于同步I/O的场景.我们以读操作为例来看看Reactor中的具体步骤:读取操作:1. 应用程序注册读就需事件和相关联的事件处理器2. 事件分离器等待 ...
- IO设计模式:Reactor和Proactor对比
IO设计模式:Reactor和Proactor对比 平时接触的开源产品如Redis.ACE,事件模型都使用的Reactor模式:而同样做事件处理的Proactor,由于操作系统的原因,相关的开源产品也 ...
- ACE_linux:Reactor与Proactor两种模式的区别
一.概念: Reactor与Proactor两种模式的区别.这里我们只关注read操作,因为write操作也是差不多的.下面是Reactor的做法: 某个事件处理器宣称它对某个socket上的读事件很 ...
- 【转载】高性能I/O设计模式Reactor和Proactor
转载自:http://blog.csdn.net/roger_77/article/details/1555170 昨天购买了<程序员>杂志 2007.4期,第一时间去翻阅了一遍,其中有一 ...
- 高性能IO设计的Reactor和Proactor模式(转)
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...
- 两种高性能 I/O 设计模式 Reactor 和 Proactor
两种高性能 I/O 设计模式 Reactor 和 Proactor Reactor 和 Proactor 是基于事件驱动,在网络编程中经常用到两种设计模式. 曾经在一个项目中用到了网络库 libeve ...
- Reactor和Proactor模式
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作.同步和异步 同步和异步是针对应用程序和内 ...
- I/O模型系列之四:两种高性能IO设计模式 Reactor 和 Proactor
不同的操作系统实现的io策略可能不一样,即使是同一个操作系统也可能存在多重io策略,常见如linux上的select,poll,epoll,面对这么多不同类型的io接口,这里需要一层抽象api来完成, ...
随机推荐
- Export SQLite data to Excel in iOS programmatically(OC)
//For the app I have that did this, the SQLite data was fairly large. Therefore, I used a background ...
- 【ARTS】01_05_左耳听风-20181210~1216
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- Nagios配置文件nagios.cfg详解
这里开始要讲一些Nagios的配置. 首先要看看目前Nagios的主配置路径下有哪些文件.[root@nagios etc]# ll总用量 152-rwxrwxr-x. 1 nagios nagios ...
- Docker手动搭建sentry错误日志系统
Sentry介绍 在开发过程中,我们通过debug来排查bug,并且使用logging来记录系统的错误.但是logging有很多不足: 必须登陆到服务器查看日志文件 需要主动去查询 输出日志方式无法把 ...
- 更改jupyter notebook的主题颜色(theme) 包括pycharm
https://blog.csdn.net/Techmonster/article/details/73382535
- 环境变量GOBIN导致GoClipse运行出现异常
Windows 10家庭中文版,go version go1.11 windows/amd64, Eclipse IDE for C/C++ Developers Photon Release (4. ...
- 使用Python自己实现简单的数据可视化
只使用Python的random库,将已有数据生成HTML格式的标签云.思路就是根据同一单词出现的次数多少,生成不同大小不同颜色单词的数据的视图. 比如以下格式的多条数据: 1 Gaming 1 Sk ...
- 一步一步学习IdentityServer3 (3)
在上一篇中配置一个基础的idrserver服务端 这篇文章将对服务端做一些变化,这里我先贴一下上一章中的代码 证书: static class Certificate { public static ...
- FileSystemResource在Srping FrameWork 5中的变化
之前在项目中一直使用FileSystemResource这个类作为PropertyPlaceholderConfigurer的Resource引入部署目录外的配置文件,并设置了setIgnoreRes ...
- 【LOJ】#2523. 「HAOI2018」奇怪的背包
题解 复杂度怎么算也要2s的题怎么0.5s就跑完了,迷啊 这个题简直算完复杂度不敢写,写了就赚飞了好吧 根据裴蜀定理,显然选出的数和P的gcd是w的约数 我们考虑枚举\(P\)的约数,上限当然是\(\ ...