/*********************************************************************
 * 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:

http://www.artima.com/articles/io_design_patterns.html

关于Reactor和Proactor的差别的更多相关文章

  1. 【转】Reactor与Proactor两种模式区别

    转自:http://www.cnblogs.com/cbscan/articles/2107494.html 两种IO多路复用方案:Reactor and Proactor 一般情况下,I/O 复用机 ...

  2. 【Network】一张图看懂 Reactor 与 Proactor 模型的区别

    首先来看看Reactor模式,Reactor模式应用于同步I/O的场景.我们以读操作为例来看看Reactor中的具体步骤:读取操作:1. 应用程序注册读就需事件和相关联的事件处理器2. 事件分离器等待 ...

  3. IO设计模式:Reactor和Proactor对比

    IO设计模式:Reactor和Proactor对比 平时接触的开源产品如Redis.ACE,事件模型都使用的Reactor模式:而同样做事件处理的Proactor,由于操作系统的原因,相关的开源产品也 ...

  4. ACE_linux:Reactor与Proactor两种模式的区别

    一.概念: Reactor与Proactor两种模式的区别.这里我们只关注read操作,因为write操作也是差不多的.下面是Reactor的做法: 某个事件处理器宣称它对某个socket上的读事件很 ...

  5. 【转载】高性能I/O设计模式Reactor和Proactor

    转载自:http://blog.csdn.net/roger_77/article/details/1555170 昨天购买了<程序员>杂志 2007.4期,第一时间去翻阅了一遍,其中有一 ...

  6. 高性能IO设计的Reactor和Proactor模式(转)

    在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...

  7. 两种高性能 I/O 设计模式 Reactor 和 Proactor

    两种高性能 I/O 设计模式 Reactor 和 Proactor Reactor 和 Proactor 是基于事件驱动,在网络编程中经常用到两种设计模式. 曾经在一个项目中用到了网络库 libeve ...

  8. Reactor和Proactor模式

    在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作.同步和异步 同步和异步是针对应用程序和内 ...

  9. I/O模型系列之四:两种高性能IO设计模式 Reactor 和 Proactor

    不同的操作系统实现的io策略可能不一样,即使是同一个操作系统也可能存在多重io策略,常见如linux上的select,poll,epoll,面对这么多不同类型的io接口,这里需要一层抽象api来完成, ...

随机推荐

  1. swift3.0之后的Error处理

    在之前的版本中,Swift中Error与OC中NSError没有关系.但是现在两者可以互相强转. 我们看看两者的区别:Error是一个实现Error协议的枚举或者结构体,对外能够获取的具体信息只有ra ...

  2. 非常有助于理解二极管PN结原理的资料

    https://www.zhihu.com/question/60053574/answer/174137061 我理解的半导体 pn 结的原理,哪里错了? https://blog.csdn.net ...

  3. 【CTF WEB】服务端请求伪造

    服务端请求伪造 如你所愿,这次可以读取所有的图片,但是域名必须是www开头 测试方法 POST /index.php HTTP/1.1 Host: 218.2.197.236:27375 Conten ...

  4. 006_mac osx 应用跨屏幕

    一般情况下 mac osx 中一个应用程序只能在一个屏幕上显示,作为从 windows 转过来的用户有点不太习惯,Goolge 后发现还是有解决方案的(虽然不是很好用). 打开 Mac 的系统偏好设置 ...

  5. Android 4.4 API

    Android 4.4 (KITKAT) 是新的 Android 平台版本,为用户和应用开发者提供了新功能.本文旨在介绍其中最值得关注的新 API. 作为应用开发者,您应尽快从 SDK 管理器下载 A ...

  6. wpf image 指定Stretch="None" 不拉伸的时候,仍然拉伸的解决办法

    I think TI82 is right on this issue. The image become bigger than you expect because its dpi doesn't ...

  7. InnoDB Lock浅谈

    数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类型有:共享锁(S).排他锁(X).意向共享(IS).意向排他(IX).为了提供更好的并发,Inn ...

  8. springMVC:将controller中数据传递到jsp页面

    1> 将方法的返回值该为ModelAndView在返回时,将数据存储在ModelAndView对象中如: newModelAndView("/WEBINF/jsp/showData.j ...

  9. 安装配置tomcat,java运行环境

    1.下载JDK,安装 官网下载地址:http://java.sun.com/javase/downloads/index.jsp 下载后,安装,选择你想把JDK安装的目录: 比如:JDK安装目录:E: ...

  10. vuejs递归组件

    vuejs学习--递归组件   前言 学习vue有一段时间了,最近使用vue做了一套后台管理系统,其中使用最多就是递归组件,也因为自己对官方文档的不熟悉使得自己踩了不少坑,今天写出来和大家一起分享. ...