不同的操作系统实现的io策略可能不一样,即使是同一个操作系统也可能存在多重io策略,常见如linux上的select,poll,epoll,面对这么多不同类型的io接口,这里需要一层抽象api来完成,所以就演变出来两种高性能的io的设计模式,分别是Reactor(同步IO)和Proactor(异步IO)。

1. Reactor 

在Reactor中,事件分离器负责等待文件描述符或socket为读写操作准备就绪,然后将就绪事件传递给对应的处理器,最后由处理器负责完成实际的读写工作。

Reactor 的标准(典型)的工作方式是:

(1)应用程序注册读就绪事件和相关联的事件处理器

(2)Reactor阻塞等待内核事件通知

(3)Reactor收到通知,然后分发可读写事件(读写准备就绪)到用户事件处理函数

(4)用户读取数据,并处理数据

(5)事件处理器完成实际的读操作,处理读到的数据,注册新的事件,然后返还控制权。

2. Proactor

Proactor 的标准(典型)的工作方式是:

(1)应用程序初始化一个异步读取操作,然后注册相应的事件处理器,此时事件处理器不关注读取就绪事件,而是关注读取完成事件,这是区别于Reactor的关键。

(2)事件分离器等待读取操作完成事件

(3)在事件分离器等待读取操作完成的时候,操作系统调用内核线程完成读取操作,并将读取的内容放入用户传递过来的缓存区中。这也是区别于Reactor的一点,Proactor中,应用程序需要传递缓存区。

(4)事件分离器捕获到读取完成事件后,激活应用程序注册的事件处理器,事件处理器直接从缓存区读取数据,而不需要进行实际的读取操作。

3. 简单的理解(抄过来的)

并发系统常使用reactor模式,代替常用的多线程的处理方式,节省系统的资源,提高系统的吞吐量。

  以一个餐饮为例,每一个人来就餐就是一个事件,他会先看一下菜单,然后点餐。就像一个网站会有很多的请求,要求服务器做一些事情。处理这些就餐事件的就需要我们的服务人员了。

(1) 在多线程处理的方式会是这样的:

一个人来就餐,一个服务员去服务,然后客人会看菜单,点菜。 服务员将菜单给后厨。

二个人来就餐,二个服务员去服务……

五个人来就餐,五个服务员去服务…

  

  (2) 在线程池处理的方式会是这样的:(固定的10个人去服务,但仍然供不应求)

  (3) Reactor设计模式: 单个线程来做多线程的事

  顾客通过呼叫服务员(event事件)通知服务员,菜单写好了,服务员就会把菜单交给厨师(事件处理器),厨师就会去做菜了。

  

  

  (4) Proactor设计模式: 让别人做完通知自己

    

    

4. 两者的区别

区别 Reactor Proactor
定义

被动的等待指示事件的到来,并作出反应,

它有一个等待的过程,做什么事都要放入到监听事件集合中等待handler可用时再操作。

直接调用异步读写操作,调用完立即返回,

由内核负责写操作,写完后调用相应的回调函数处理后续逻辑。

实现

实现了一个被动的事件分离和分发模型

服务等待请求事件的到来,再通过不间断地同步处理事件做出反应。

实现了一个主动的事件分离和分发模型。

允许多个任务并发的执行,从而提高吞吐量,可执行耗时长的任务。

主动与被动 被动 主动
同步与异步 同步 异步
优点

1. 简单。实现相对简单,对于耗时短的处理场景处理高效。

2. 单线程。操作系统可在多个事件源上等待。避免了多线程编程相关的性能开销和编程复杂性。

3. 不用锁。事件的串行化对应用时透明的,可以顺序的同步执行而不需加锁。

4. 事务隔离。将与应用无关的   多路分解和分配机制 与应用相关的   回调函数  分离开来

性能更高,能够处理耗时长的并发场景。
缺点

处理耗时长的操作会造成事务分发的阻塞,影响后续事件的处理。

1. 复杂。实现逻辑复杂。

2. 依赖OS对异步的支持(很少很难)

使用场景

同时接受多个服务请求,并且依次同步的处理他们的事件驱动程序。

耗时短的。

异步接受和同时处理多个服务请求的事件驱动程序

耗时长的。

五.总结

基于事件驱动的网络编程的两种设计模式:

  Reactor (反应堆 同步IO)  java NIO  多路复用IO  redis libevent  Linux epoll

  Proactor(前摄器 异步IO)  java AIO  异步IO模型  目前只有 Windows IO completion port.(iocp)模型

  1. 只有IOCP是asynchronous I/O,其他机制或多或少都会有一点阻塞。
  2. select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善
  3. epoll, kqueue、select是Reacor模式,IOCP是Proactor模式。
  4. java nio包是select模型。
  5. epoll, kqueue、select 等是IO策略,他们属于设计模式,他们实现设计模式,相对于设计模式,设计策略更细节,设计模式更抽象。

摘录网址:

I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor

IO设计模式之Reactor和Proactor

reactor和proactor模式

Reactor模式,或者叫反应器模式

I/O模型系列之四:两种高性能IO设计模式 Reactor 和 Proactor的更多相关文章

  1. I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor

    目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...

  2. I/O模型之四:Java 浅析I/O模型(BIO、NIO、AIO、Reactor、Proactor)

    目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...

  3. 两种高性能I/O设计模式(Reactor/Proactor)的比较

    原文出处: Alex Libman   译文出处:潘孙友   欢迎分享原创到伯乐头条 综述 这篇文章探讨并比较两种用于TCP服务器的高性能设计模式. 除了介绍现有的解决方案,还提出了一种更具伸缩性,只 ...

  4. [转]两种高性能I/O设计模式(Reactor/Proactor)的比较

    [原文地址:http://www.cppblog.com/pansunyou/archive/2011/01/26/io_design_patterns.html] 综述 这篇文章探讨并比较两种用于T ...

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

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

  6. Jenkins持续集成企业实战系列之两种网站部署的流程-----01

    注:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.    最初接触Jenkins也是由于公司需求,根据公司需求Java代码项目升级的.(公司是 ...

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

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

  8. sklearn 中模型保存的两种方法

    一. sklearn中提供了高效的模型持久化模块joblib,将模型保存至硬盘. from sklearn.externals import joblib #lr是一个LogisticRegressi ...

  9. LINQ to Objects系列(2)两种查询语法介绍

    LINQ为我们提供了两种查询语法,分别是查询表达式和查询方法语法.这篇文章分为以下几个方面进行总结. 1,一个包含两种查询语法的简单示例 2,查询表达式的结构 3,查询方法相关的运算符 一个包含两种查 ...

随机推荐

  1. 深入浅出KNN算法(一) KNN算法原理

    一.KNN算法概述 KNN可以说是最简单的分类算法之一,同时,它也是最常用的分类算法之一,注意KNN算法是有监督学习中的分类算法,它看起来和另一个机器学习算法Kmeans有点像(Kmeans是无监督学 ...

  2. Testlink1.9.17使用方法(第二章 登录&汉化设置)

    第二章 登录&汉化设置 QQ交流群:585499566 1,使用超级账户admin/admin登录. 2,登录后,会提示创建一个新的项目,先不要创建,先进入用户管理,设置成中文显示,也就是汉化 ...

  3. git开发常用命令

    1.基本命令git branch 查看本地分支git branch -r 查看远程分支git checkout xxx 切换分支git pull origin master //从远程同步到本地,ma ...

  4. shiro经典通俗易懂javase例子

    package com.cun; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org. ...

  5. eclipse启动报.log错误

    解决办法: windows: D:\Program Files\eclipse\eclipse.ini 在文件末尾添加一行: --add-modules=ALL-SYSTEM

  6. Webstorm 2017.3激活破解

    之前尝试过各种激活破解办法,不过随着版本的不断升级,激活信息都失效了(毕竟咱不是通过正常途径激活的),只能重新激活.而且难度越来越大,记得早先网上有人分享激活码,激活的server地址,破解程序等等, ...

  7. 深入研究 Mini ASP.NET Core(迷你 ASP.NET Core),看看 ASP.NET Core 内部到底是如何运行的

    前言 几年前,Artech 老师写过一个 Mini MVC,用简单的代码告诉读者 ASP.NET MVC 内部到底是如何运行的.当时我研究完以后,受益匪浅,内心充满了对 Artech 老师的感激,然后 ...

  8. 启用shopt 选项实现不使用 CD 命令进入目录/文件夹

    众所周知,如果没有 cd 命令,我们无法 Linux 中切换目录.这个没错,但我们有一个名为 shopt 的 Linux 内置命令能帮助我们解决这个问题. shopt 是一个 shell 内置命令,用 ...

  9. Counting Sort(Java)

    public static void countingsort(int[] a, int n) //n = a.length { int max = a[0], min = a[0]; for(int ...

  10. C#字符串和ASCII码的转换

    //字符转ASCII码: public static int Asc(string character) { if (character.Length == 1) { System.Text.ASCI ...