I/O模型系列之四:两种高性能IO设计模式 Reactor 和 Proactor
不同的操作系统实现的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)模型
- 只有IOCP是asynchronous I/O,其他机制或多或少都会有一点阻塞。
- select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善
- epoll, kqueue、select是Reacor模式,IOCP是Proactor模式。
- java nio包是select模型。
- epoll, kqueue、select 等是IO策略,他们属于设计模式,他们实现设计模式,相对于设计模式,设计策略更细节,设计模式更抽象。
摘录网址:
I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor
I/O模型系列之四:两种高性能IO设计模式 Reactor 和 Proactor的更多相关文章
- I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor
目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...
- 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 ...
- 两种高性能I/O设计模式(Reactor/Proactor)的比较
原文出处: Alex Libman 译文出处:潘孙友 欢迎分享原创到伯乐头条 综述 这篇文章探讨并比较两种用于TCP服务器的高性能设计模式. 除了介绍现有的解决方案,还提出了一种更具伸缩性,只 ...
- [转]两种高性能I/O设计模式(Reactor/Proactor)的比较
[原文地址:http://www.cppblog.com/pansunyou/archive/2011/01/26/io_design_patterns.html] 综述 这篇文章探讨并比较两种用于T ...
- 两种高性能 I/O 设计模式 Reactor 和 Proactor
两种高性能 I/O 设计模式 Reactor 和 Proactor Reactor 和 Proactor 是基于事件驱动,在网络编程中经常用到两种设计模式. 曾经在一个项目中用到了网络库 libeve ...
- Jenkins持续集成企业实战系列之两种网站部署的流程-----01
注:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任. 最初接触Jenkins也是由于公司需求,根据公司需求Java代码项目升级的.(公司是 ...
- 【转载】高性能I/O设计模式Reactor和Proactor
转载自:http://blog.csdn.net/roger_77/article/details/1555170 昨天购买了<程序员>杂志 2007.4期,第一时间去翻阅了一遍,其中有一 ...
- sklearn 中模型保存的两种方法
一. sklearn中提供了高效的模型持久化模块joblib,将模型保存至硬盘. from sklearn.externals import joblib #lr是一个LogisticRegressi ...
- LINQ to Objects系列(2)两种查询语法介绍
LINQ为我们提供了两种查询语法,分别是查询表达式和查询方法语法.这篇文章分为以下几个方面进行总结. 1,一个包含两种查询语法的简单示例 2,查询表达式的结构 3,查询方法相关的运算符 一个包含两种查 ...
随机推荐
- 深入浅出KNN算法(一) KNN算法原理
一.KNN算法概述 KNN可以说是最简单的分类算法之一,同时,它也是最常用的分类算法之一,注意KNN算法是有监督学习中的分类算法,它看起来和另一个机器学习算法Kmeans有点像(Kmeans是无监督学 ...
- Testlink1.9.17使用方法(第二章 登录&汉化设置)
第二章 登录&汉化设置 QQ交流群:585499566 1,使用超级账户admin/admin登录. 2,登录后,会提示创建一个新的项目,先不要创建,先进入用户管理,设置成中文显示,也就是汉化 ...
- git开发常用命令
1.基本命令git branch 查看本地分支git branch -r 查看远程分支git checkout xxx 切换分支git pull origin master //从远程同步到本地,ma ...
- shiro经典通俗易懂javase例子
package com.cun; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org. ...
- eclipse启动报.log错误
解决办法: windows: D:\Program Files\eclipse\eclipse.ini 在文件末尾添加一行: --add-modules=ALL-SYSTEM
- Webstorm 2017.3激活破解
之前尝试过各种激活破解办法,不过随着版本的不断升级,激活信息都失效了(毕竟咱不是通过正常途径激活的),只能重新激活.而且难度越来越大,记得早先网上有人分享激活码,激活的server地址,破解程序等等, ...
- 深入研究 Mini ASP.NET Core(迷你 ASP.NET Core),看看 ASP.NET Core 内部到底是如何运行的
前言 几年前,Artech 老师写过一个 Mini MVC,用简单的代码告诉读者 ASP.NET MVC 内部到底是如何运行的.当时我研究完以后,受益匪浅,内心充满了对 Artech 老师的感激,然后 ...
- 启用shopt 选项实现不使用 CD 命令进入目录/文件夹
众所周知,如果没有 cd 命令,我们无法 Linux 中切换目录.这个没错,但我们有一个名为 shopt 的 Linux 内置命令能帮助我们解决这个问题. shopt 是一个 shell 内置命令,用 ...
- Counting Sort(Java)
public static void countingsort(int[] a, int n) //n = a.length { int max = a[0], min = a[0]; for(int ...
- C#字符串和ASCII码的转换
//字符转ASCII码: public static int Asc(string character) { if (character.Length == 1) { System.Text.ASCI ...