事件驱动模式--Reactor
原文:https://www.cnblogs.com/harvyxu/p/7498763.html
1 Reactor模型
Reactor模式是处理并发I/O比较常见的一种模式,用于同步I/O,中心思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/O事件到来或是准备就绪(文件描述符或socket可读、写),多路复用器返回并将事先注册的相应I/O事件分发到对应的处理器中。
Reactor是一种事件驱动机制,和普通函数调用的不同之处在于:应用程序不是主动的调用某个API完成处理,而是恰恰相反,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,如果相应的事件发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”。用“好莱坞原则”来形容Reactor再合适不过了:不要打电话给我们,我们会打电话通知你。
Reactor模式与Observer模式在某些方面极为相似:当一个主体发生改变时,所有依属体都得到通知。不过,观察者模式与单个事件源关联,而反应器模式则与多个事件源关联 。
Reactor模型各模块之间的关系如下图所示:
- Handle(描述符): 即操作系统中的句柄fd,是对资源在操作系统层面上的一种抽象,它可以是打开的文件、一个连接(Socket)、Timer等。将这个句柄fd注册到Synchronous Event Demultiplexer中,以监听Handle上发生的事件,可以是CONNECT事件,也可以是READ、WRITE、CLOSE事件等。
- Synchronous Event Demultiplexer(同步事件多路分离器): 阻塞等待被监听的事件集fd_set中的事件发生。等待事件一般使用I/O复用技术实现,在linux系统上一般是select、poll、epol_waitl等系统调用,用来等待一个或多个事件的发生。I/O框架库一般将各种I/O复用系统调用封装成统一的接口,称为事件多路分离器。调用者会被阻塞,直到分离器的描述符集上有事件发生。
- Initiation Dispatcher(启动调度器):用于管理Event Handler,负责注册、移除EventHandler等,如将EventHandler(事件处理器)注册为响应fd对应事件的回调函数;另外,它还作为Reactor模式的入口,调用Synchronous Event Demultiplexer的select方法阻塞等待事件的发生;当阻塞等待返回时,根据事件发生的Handle将其分发给对应的Event Handler处理,即回调EventHandler中的handle_event()方法。
- Event Handler(事件处理器):I/O框架库提供的事件处理器通常是由一个或多个模板函数组成的接口。这些模板函数描述了和应用程序相关的对某个事件的操作,用户需要继承它来实现自己的事件处理器,即具体事件处理器。因此,事件处理器中的回调函数一般声明为虚函数,以支持用户拓展。
- Concrete Event Handler(具体的事件处理器):是事件处理器接口的实现。它实现了应用程序提供的某个服务。每个具体的事件处理器总和一个描述符相关。它使用描述符来识别事件、识别应用程序提供的服务。
2 Reactor的几种模式
在web服务中,很多都涉及基本的操作:read request、decode request、process service、encod reply、send reply等。
(1) 单线程模式
这是最简单的单Reactor单线程模型。Reactor线程是个多面手,负责多路分离套接字,Accept新连接,并分派请求到处理器链中。该模型适用于处理器链中业务处理组件能快速完成的场景。不过这种单线程模型不能充分利用多核资源,所以实际使用的不多。
(2) 多线程模式(单Reactor)
该模型在事件处理器(Handler)链部分采用了多线程(线程池),也是后端程序常用的模型。
(3) 多线程模式(多个Reactor)
比起第二种模型,它是将Reactor分成两部分,mainReactor负责监听并accept新连接,然后将建立的socket通过多路复用器(Acceptor)分派给subReactor。subReactor负责多路分离已连接的socket,读写网络数据;业务处理功能,其交给worker线程池完成。通常,subReactor个数上可与CPU个数等同。
参考:
两种高效的服务器设计模型:Reactor和Proactor模型
事件驱动模式--Reactor的更多相关文章
- java高并发实战Netty+协程(Fiber)|系列1(续)|事件驱动模式和零拷贝
上次讲到事件驱动模式,今天我们来好好分析下netty的事件模式的几个类型. 先从NIO讲起, JAVA NIO方面Selector给Reactor模式提供了基础,Netty结合Selector和Rea ...
- java高并发实战Netty+协程(Fiber)|系列1|事件驱动模式和零拷贝
今天开始写一些高并发实战系列. 本系列主要讲两大主流框架: Netty和Quasar(java纤程库) 先介绍netty吧,netty是业界比较成熟的高性能异步NIO框架. 简单来说,它就是对NIO2 ...
- 反应堆模式(reactor)
在提到高性能服务器编程的时候肯定有听过reactor模式,如果只是简单的写一个服务器和客户端建立连接的程序来熟悉一下使用socket函数编程,一般这种情况都是同步方式实现的,服务器阻塞等待客户端的连接 ...
- 干掉Switch-Case、If-Else----订阅发布模式+事件驱动模式
在上位机和下位机或者服务端和客户端通信的时候,很多时候可能为了赶项目进度或者写代码方便直接使用Socket通信,传输string类型的关键字驱动对应的事件,这就有可能导致程序中存在大量的Switch- ...
- 彻底搞懂彻底搞懂事件驱动模型 - Reactor
在高性能网络技术中,大家应该经常会看到Reactor模型.并且很多开源软件中都使用了这个模型,如:Redis.Nginx.Memcache.Netty等. 刚开始接触时可能一头雾水,这到底是个什么东东 ...
- 配置Apache运行在event事件驱动模式下
(1)启用MPM Include conf/extra/httpd-mpm.conf (2)配置evnet MPM参数 <IfModule event.c> #default 3 Ser ...
- SaltStack事件驱动 – event reactor
Event是SaltStack里面的对每个事件的一个记录,它相比job更加底层,Event能记录更加详细的SaltStack事件,比如Minion服务启动后请求Master签发证书或者证书校验的过程, ...
- 不识Netty真面目,只缘未读此真经
Netty官网:https://netty.io/ Netty is an asynchronous event-driven network application framework for ra ...
- Reactor模式
对象行为类的设计模式,对同步事件分拣和派发.别名Dispatcher(分发器) Reactor模式是处理并发I/O比较常见的一种模式,用于同步I/O,中心思想是将所有要处理的I/O事件注册到一个中心I ...
随机推荐
- [JS][jQuery]清空元素html("")、innerHTML="" 与 empty()的差别:关于内容泄露问题
清空元素html("").innerHTML="" 与 empty()的差别 一.清空元素的差别 1.错误做法一: $(&quo ...
- 【电子签章】HTML格式合同转化成PDF文件
代码地址如下:http://www.demodashi.com/demo/12476.html 一.主要思路 通过itextpdf 生成想要的pdf 文件 通过itextpdf 中 XMLWorker ...
- linux下robotframework执行测试用例的几种方法
1.执行指定的测试用例文件(Test Suite) [root@localhost cases]# pybot purge.txt 2.执行整个porject目录下的所有测试用例 ...
- 字符串== equals
经常碰到比较字符串的题, eg: public class StringDemo{ private static final String MESSAGE = "taobao"; ...
- 使用Nginx的proxy_cache缓存功能取代Squid
Nginx从0.7.48版本开始,支持了类似Squid的缓存功能.这个缓存是把URL及相关组合当作Key,用md5编码哈希后保存在硬盘上,所以它可以支持任意URL链接,同时也支持404/301/302 ...
- neural network and deep learning笔记(1)
neural network and deep learning 这本书看了陆陆续续看了好几遍了,但每次都会有不一样的收获. DL领域的paper日新月异.每天都会有非常多新的idea出来,我想.深入 ...
- JS 的引用赋值与传值赋值
这个问题说大不大说小不小,如果你有幸踩了这个坑,一定会找这篇文章,哈哈~ 现说一下JS数字的类型:基本类型和引用类型 先看下下面两个栗子: var a = 30; var b = a; a = 20; ...
- Spark源代码分析之六:Task调度(二)
话说在<Spark源代码分析之五:Task调度(一)>一文中,我们对Task调度分析到了DriverEndpoint的makeOffers()方法.这种方法针对接收到的ReviveOffe ...
- 关于gcc
1 the architecture of gcc 2 自己编译gcc时的 --build --host --target选项的含义和用法 <1> --build 执行本次的gcc编译的主 ...
- 我的Android进阶之旅------>Android中ListView中嵌套(ListView)控件时item的点击事件不起作的问题解决方法
开发中常常需要自己定义Listview,去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点. 如果你的自定义Li ...