ACE中的Proactor和Reactor

2023-12-06 20:18
文章标签 reactor ace proactor

本文主要是介绍ACE中的Proactor和Reactor,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ACE中的Proactor和Reactor



        ACE_Select_Reactor是除Windows之外所有平台使用的默认反应器实现,在这些系统上最终会用select()系统函数进行等待。在Windows上ACE_WFMO_Reactor是默认的反应器实现。该实现没有使用select()多路分离器,而是使用了WaitForMultipleObjects()。在使用ACE_WFMO_Reactor时,需要一些权衡:ACE_WFMO_Reactor只能登记62个句柄。底层的WaitForMutipleObejcts()函数是64个,ACE在内部使用了其中的两个;I/O类型,ACE_WFMO_Reactor只在socket句柄上支持handler_input()、handler_output()和handler_exception()的I/O回调;只要句柄能用于WaitForMultipleObjects(),ACE_WFMO_Reactor就能对其做出反应,比如文件变更通知句柄和事件句柄。

       ACE_WIN32_Proactor是Windows上的ACE_Proactor实现,它使用I/O完成多口进行完成事件检测。在初始化异步操作工厂时(比如ACE_Asynch_Read_Stream或ACE_Aysnch_Write_Stream),I/O句柄会与Proactor的I/O完成端口关联在一起。在这种实现里,Windows的GetQueuedCompletionStatus()函数用于执行时间循环。多个线程可以同时执行ACE_WIN32_Proactor时间循环。POSIX系统上的ACE Proactor实现提供了多种用于发起I/O操作、并检查其完成的机制。ACE所封装的POSIX异步I/O机制支持read()和write()操作,但不支持与TCP/IP连接相关的操作,为了支持ACE_Asynch_Acceptro和ACE_Asynch_Connector的函数,ACE使用了一个单独的线程来执行与连接有关的操作。因此,在POSIX平台上使用Proactor框架时,程序将会运行多个线程。ACE的内部机制使得你不用再多个线程中对时间进行处理,所以你无需增加任何特殊的加锁或同步。

        首先想写网络处理程序,那么要清楚各个步骤的限制是什么,简单的说,肯定有读取(写)数据,和处理数据两个部分,那么这个两个部分有什么特点呢?读取数据主要是I/O操作,而单个的I/O操作可能会有等待,而且I/O操作对CPU的耗费很少,最重要的是I/O速度与CPU速度比跟龟速差不多。一个线程就可以处理很多路的I/O操作,在一次I/O完成的时候会激活分离器,由分离器调用事件处理器。做个假设,可能同时有1000个数据请求,如果不用reactor,那么可能会开启1000个线程或者进程进行服务,这个时候首先线程之间的切换和锁开销是非常大的,而如果采用reactor,可能会只用一个读线程,轮流读取这1000个请求,然后当其中的一个读取完成后,激活分离器,分离器调用事件处理器,这样的话,如果系统处理数据很快的话,那么同时存在的线程可能很少,就减少了系统的线程创建切换和销毁。

        记得以前写过的服务器程序,都是有一个读取请求线程池,一个处理线程池,这样的话其实和Reactor模式的原理差不多,把读取和处理分离开来,然后用一个消息队列来完成读取与处理的通信,这样会用到锁,锁的设计不仅复杂而且会有系统开销。但是Reactor没有用锁,只把一个buffer告诉分发器,当读取结束就回调处理handler。(在ACE中是否用锁实现的不是很确定)而且,想刚才那样设计交互就比较麻烦,如果光是读还比较简单,但是读到如果会送那么就比较麻烦了。

下面是别的博文上总结Reactor和Proactor的读的过程:

在Reactor中实现读:
- 注册读就绪事件和相应的事件处理器
- 事件分离器等待事件
- 事件到来,激活分离器,分离器调用事件对应的处理器。

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

在Proactor中实现读:
- 处理器发起异步读操作(注意:操作系统必须支持异步IO)。在这种情况下,处理器无视IO就绪事件,它关注的是完成事件。
- 事件分离器等待操作完成事件
- 在分离器等待过程中,操作系统利用并行的内核线程执行实际的读操作,并将结果数据存入用户自定义缓冲区,最后通知事件分离器读操作完成。
- 事件分离器呼唤处理器。
- 事件处理器处理用户自定义缓冲区中的数据,然后启动一个新的异步操作,并将控制权返回事件分离器


简单总结下相同点与不同点:
相同点
1)都有Event Demutiplexer(为什么叫事件多路分离器呢?主要是从它的功能上看,它能够把事件源的I/O时间分离出来,并分发到对应的read/write事件处理区(Event Handler)),负责回调handler。
2)读(写)数据,与读结束后处理为分开的两个过程,这也是Reactor的重点所在,不用一个线程完成从读数据一直到处理结束,读数据线程和处理线程是两个不同的线程。这样做有个优点,因为读取数据可能会很耗费时间,读取其实瓶颈为系统的I/O,一个线程就可以处理很多路数据的I/O处理。

不同点:
1)Proactor是在I/O操作完成才回调handler,而Reactor是在I/O可以进行读或写操作时候调用handler。
2)Proactor的读写是利用操作系统支持异步I/O读写操作完成的,而Reactor的I/O操作是由用户完成的。
3)Reactor为同步的,需要用户自己去执行I/O操作然后等待I/O操作完成,在执行某些操作,Proactor为异步的,发起I/O操作后就交给操作系统了,只关心IO完成事件。这里一开始理解有个小的误区,


        其实Reactor和Proactor在等待I/O事件到来的时候都可以理解为异步的,可能都用到select()底层函数,当端口可操作时候由操作系统异步的通知,这个时候Reactor收到通知,调用handler。然而Proactor收到端口可操作的时候还不满意,需要在I/O操作完成后再异步的通知,这样Proactor相当于两层异步操作,而说Reactor和Proactor的“异步”,指的为后面的I/O操作。

        “Reactor框架中用户定义的操作是在实际操作之前调用的。比如你定义了操作是要向一个SOCKET写数据,那么当该SOCKET可以接收数据的时候,你的操作就会被调用;而Proactor框架中用户定义的操作是在实际操作之后调用的。比如你定义了一个操作要显示从SOCKET中读入的数据,那么当读操作完成以后,你的操作才会被调用。”

参考:

http://www.cnblogs.com/dawen/archive/2011/05/18/2050358.html
http://name5566.com/4175.html

这篇关于ACE中的Proactor和Reactor的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/463173

相关文章

C#通过ACE OLEDB驱动程序访问 Access和 Excel

ACE 代表 Access Connectivity Engine。它是 Microsoft 提供的一组组件,用于访问和操作 Microsoft Access 数据库以及其他类似的文件格式,如 Excel 工作簿。ACE 主要包括以下几部分: ACE OLEDB 驱动程序:用于通过 OLE DB 提供程序访问 Access 数据库和 Excel 文件。例如,Microsoft.ACE.OLED

Netty源码解析2-Reactor

请戳GitHub原文: https://github.com/wangzhiwubigdata/God-Of-BigData 更多文章关注:多线程/集合/分布式/Netty/NIO/RPC Java高级特性增强-集合Java高级特性增强-多线程Java高级特性增强-SynchronizedJava高级特性增强-volatileJava高级特性增强-并发集合框架Java高级特性增强-

服务器模型 Reactor 和 Proactor

Proactor 具体流程如下: 处理器发起异步操作,并关注 IO 完成事件;事件分离器等待操作完成事件;分离器等待过程中,内核并行执行实际的 IO 操作,并将结果存储入用户自定义的缓冲区,最后通知事件分离器读操作完成;IO 完成后,通过事件分离器呼唤处理器;事件处理器处理用户自定义的缓冲区中的数据 Proactor 的所有 IO 操作都交给系统提供的异步 IO 接口去执行。工作线程

reactor架构模式

http://www.cnblogs.com/hzbook/archive/2012/07/19/2599698.html

利用ace.js编写一个JavaScript编辑器(带智能补全)

<html lang="en"><head><title>javascript编辑器</title><style type="text/css" media="screen">#aaa { width:50%;}#editor { width:100%;padding-bottom: 35%;}#iframe1{width:100%;background: #505050

【AMBA Bus ACE 总线11 -- ACE DVM(Distributed Virtual Memory)使用介绍】

文章目录 ACE DVM 使用背景DVM Transactions 类型和作用DVM 消息使用场景DVM 示例Sumamry ACE DVM 使用背景 当 Cache maintenance 指令操作完以后,落实到总线上的时候,它会有一组 cache maintenance transaction 出来,这组 cache maintenance transaction 主要是

react Ace 编辑器,快捷键、代码提示

1. 安装命令 npm install react-ace 2.导入相关配置 import AceEditor from 'react-ace';//language_tools语言工具,代码提示工具import 'brace/ext/language_tools';//searchbox过滤框,快捷键ctrl+Fimport 'brace/ext/searchbox';//一下i

从io模型到ppc,tpc,reactor,preactor

所有的系统I/O都分为两个阶段:等待就绪和操作.读就是等待系统可读和真正的读;写就是等待系统可写和真正的写. 1.网络io模型 这是我们常见的一张图. 1.传统的bio,就是同步阻塞的.当调用socket.read的时候.会阻塞. 直到系统可读/写;当真正去执行读的时候(内核-->用户),还是阻塞. 对应的优化方式有ppc/tpc(下面的1.1 和 1.2) 2.非阻塞io,当调用

高性能Server---Reactor模型

转载地址:http://www.ivaneye.com/2016/07/23/iomodel.html 在这个充斥着云的时代,我们使用的软件可以说99%都是C/S架构的! 你发邮件用的Outlook,Foxmail等你看视频用的优酷,土豆等你写文档用的Office365,googleDoc,Evernote等你浏览网页用的IE,Chrome等(B/S是特殊的C/S)…… C/S架构的软件

C语言实现Reactor

​ 在前边的C语言实现简易tcp服务器中,我们实现服务器是采用了最笨拙的方法,就是每来一个客户端,我们就创建一个线程进行连接处理。试想如果有10w个客户端来,就需要10w个线程,需要创建大量的线程,耗费大量的资源,并且为了保证线程安全,还需要考虑锁,死锁等问题,这些都需要一定的开销。因此为了解决这个问题,我们下一篇介绍了select、poll、epoll,他们三个是常用的I/O多路复用机制。解决了