/*********************************************************************
 * 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. 【转】2019年3月 最新win10激活密匙 win10各版本永久激活序列号 win10正式版激活码分享

    现在市面上大致有两种主流激活方法,一种是通过激活码来激活,另外一种是通过激活工具来激活.但是激活工具有个弊端就是激活时间只有180天,很多网友都想要永久激活,现在已经过了win10系统免费推广期了,所 ...

  2. arm GIC介绍之四【转】

    转自:https://blog.csdn.net/sunsissy/article/details/73882718 GIC是ARM体系中重要的组件,在认识到GIC的组成和功能之后,了解到IRQ的大致 ...

  3. ssh远程免密登录Linux

    一.在本地机器创建公钥,一路回车即可 ssh-keygen -t rsa 二.发送公钥到远程服务器端 如果是默认端口:scp id_rsa.pub user@ip:~/.shh 如果远程服务器设置的是 ...

  4. Centos7下yum安装zabbix-server的部署(一)

    一.环境准备 OS:CentOS 7.2 64bit Zabbix版本:3.0.12 MySQL版本:5.6 hostname ip 主机用途zabbix-server 10.0.0.44 服务端 z ...

  5. IdentityServer4结合AspNetCore.Identity实现登录认证踩坑填坑记录

    也可以自定义实现,不使用IdentityServer4.AspNetIdentity这个包,当然还要实现其他接口IResourceOwnerPasswordValidator. IProfileSer ...

  6. IScroll5安卓重复点击兼容问题处理

    最近在做移动web开发,使用IScroll 5 的时候出现了设备之间兼容的问题: 情景如下: Android手机:点击滚动区间内的选项时出现点击时间重叠(类似事件冒泡的行为)问题 Apple手机:木有 ...

  7. kgtemp文件转mp3工具

    kgtemp文件是酷我音乐软件的缓存文件,本文从技术层面探讨如何解密该文件为mp3文件,并通过读取ID3信息来重命名. kgtemp解密 kgtemp文件前1024个字节是固定的包头信息,解密方案详细 ...

  8. vuejs、eggjs、mqtt

    vuejs.eggjs.mqtt全栈式开发设备管理系统 vuejs.eggjs.mqtt全栈式开发简单设备管理系统 业余时间用eggjs.vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据 ...

  9. Noip2018游记——AFO

    本来Day 0和Day 1写得挺轻松的,结果没想到Day 2是这样的画风...心情逐渐沉重... Day 0 白天的时候颓的一批,上午考的信心赛还打错了一个字母然后$100pts\rightarrow ...

  10. ajax和302(转)

    原文:http://www.cnblogs.com/dudu/p/ajax_302_found.html 在ajax请求中,如果服务器端的响应是302 Found,在ajax的回调函数中能够获取这个状 ...