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,查询方法相关的运算符 一个包含两种查 ...
随机推荐
- Django-0-环境搭建、创建项目、启动服务
1- 创建虚拟环境名称(在虚拟机中) mkvirtualenv -p /usr/bin/python3 envname (/usr/bin/python3 - 你自己在虚拟机中的Python解释器 ...
- memcached架构及缓存策略
----------------------------------------概述---------------------------------------- Memcached是一套高性能分布 ...
- 考据:internet 和 Web
我们有时大谈互联网发展趋势,有时讨论Web开发:有时说因特网如何,有时又说万维网怎样.但身处其间我们,有时雾里看花,对有些东西一知半解,这里对internet和Web进行一个简单梳理(很多东西缺少可信 ...
- C/C++中容器vector用法
C++中数组非常坑,有没有相似Python中list的数据类型呢?相似的就是vector!vector 是同一种类型的对象的集合,每一个对象都有一个对应的整数索引值. 和 string 对象一样.标准 ...
- 【vue】使用vue+element搭建项目,Tree树形控件使用
1.依赖安装 本例中,使用render-content进行树节点内容的自定义,因此需要支持JSX语法.(见参考资料第3个) 在Git bash中运行一下指令 cnpm install\ babel-p ...
- DOM中获取宽高、位置总结
原生JS 一.文档.窗口的宽高和位置 // 获取屏幕的宽高 window.screen.height | window.screen.width // 屏幕可用工作区宽高 window.screen. ...
- Scrum Meeting 博客
笨拙软件工程 Scrum Meeting 博客汇总 一.Alpha阶段 [alpha阶段]第一次Scrum Meeting [alpha阶段]第二次Scrum Meeting [alpha阶段]第三次 ...
- Socket网络编程(案例)
Socket:套接字 java.net包 1.流式套接字:基于TCP协议的Socket网络编程 工作方式: 1.客户端A连接到服务器: 2.服务器建立连接并把客户端A添加到列表: 3.客户端B.C.. ...
- JS JavaScript模块化(ES Module/CommonJS/AMD/CMD)
前言 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了, jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得 ...
- MySQL数据库聚合函数
+++++++++++++++++++++++++++++++++++++++++++标题:MySQL数据库聚合函数时间:2019年2月25日内容:MySQL数据库聚合函数重点:MySQL数据库聚合函 ...