[Design Pattern] Reactor模式

参考资料



• 维基百科:https://en.wikipedia.org/wiki/Reactor_pattern

事件驱动模式



我们已经知道,当前对于一台主机,其CPU的处理速度是要远远高于IO的处理速度。如果为了一个IO操作(譬如从Socket收取一段数据),应用程序阻塞等待IO操作的完成是不划算的,这将白白浪费分配给进程的CPU时间。好一些的做法是分配多个进程或多个线程进行IO处理,但这样又会带来进程切换或线程切换的开销。考虑这样的情况,某个进程读取一段数据将花费500ms,在这期间切换到该进程3次,但此时什么都不能处理,白白浪费CPU时间。事件驱动模式,或者称为事件回调方式的提出,可以有效地解决这个问题。这种方式下,应用层业务向一个“中间人”注册一个事件回调服务(Event Handler),当IO就绪(可读或可写)时,该“中间人”抛出一个事件,并通知相应的事件回调函数进行处理。事件回调方式也正是“好莱坞原则”(Hollywood Principle : Don‘t call us, we‘ll call you)在软件开发中的一个体现。

其实事件驱动模式可以很容易在现实生活中找到对应的场景,以餐饮服务为例:每一个顾客前来就餐时将发出一个服务请求(Request),然后浏览菜单,最后进行点餐。这个过程中需要我们服务人员处理这些就餐请求。在多线程处理模式下,会是这样的过程:一个顾客开就餐,需要一个服务员前往服务,顾客浏览菜单,然后点菜,最后服务人员将菜单递交给后厨。当5个人同时落座就餐,就需要5个服务员同时前往服务。这就是多线程的处理思路,一个业务请求到达时就需要一个专门的线程进行处理。这种方式在人比较少的时候获得较好的用户体验,每个顾客都能及时得到服务。在这种服务态度下,这家店的口碑得到认可,于是前来吃饭的顾客多了起来,于是同一时间会来10个顾客就餐。餐厅老板很开心,但此时只有5个服务员,为了不降低服务品质,老板又聘请了5个服务员。越来越多的人对这家餐厅表示满意,顾客渐渐多了起来,同时前来吃饭的人到达了20,这时候老板犯愁了,如果再聘请10个服务员,势必会影响餐厅收入的利润;如果不聘请服务员,而某些正在接收服务员服务的顾客点菜很慢,这样势必会降低其他顾客的服务质量。老板后来观察发现,大多数客人点菜的过程是比较慢的,服务员的时间闲置在等待客人点菜的过程中,于是老板终于发现了一个新的方法:当客人浏览菜单的时候,服务员可以前往招呼其他客人,等客人浏览完菜单,招呼一声“服务员”,马上就会有个服务员前往服务。客人招呼服务员就是发起了一个事件(Event),服务员前往服务就是此事件的回调服务(Event Handler)。最终老板根据业务并发量留下了合适数量的服务员。

Reactor模式简介



系统I/O处理方式一般可分为阻塞非阻塞同步非阻塞异步三种。这三种方式中,非阻塞异步模式的扩展性和性能最好。非阻塞异步模式可以用多种IO多路复用机制实现,譬如Reactor模式Proactor模式。在Reactor模式里,操作系统只负责通知IO就绪,而具体的IO操作仍然由业务进程中阻塞处理;Proactor模式则在此基础上更进一步,由操作系统将IO操作执行完毕,而事件处理过程只负责处理业务逻辑,做到了IO与程序处理异步执行。因此我们一般称Reactor模式同步IO模式,而Proactor模式异步IO模式

一般I/O多路复用机制都依赖一个事件多路分离器(Event Demultiplexer)。事件多路分离器对象可将来自事件源的IO事件(Event)分离出来,并分发到对应的IO事件处理器(Event Handler)中。开发人员需要预先注册事件及其事件处理器(或回调函数)。两个与事件多路分离器有关的设计模式是上面提及的Reactor模式Proactor模式

       Reactor模式目标是在应用中,基于事件驱动机制将一个或多个用户服务请求分离(Demultiplex)并调度(Dispatch)给应用程序,使得应用程序能同步有序地处理同时接收的多个服务请求。

Reactor模式详解


• UML结构图

• 结构说明

在Reactor模式中,有5个关键的参与者。

? 事件源 - Resource Handle

? 同步事件分离器 - Synchronous Event Demultiplexer

时间: 2024-08-08 18:33:04

[Design Pattern] Reactor模式的相关文章

Bridge Design Pattern (桥模式)

桥模式的核心思想在于:抽象和行为分离. 在JDON里面,板桥里人举的例子是咖啡(抽象)与加奶(行为)的关系.原文(http://www.jdon.com/designpatterns/bridge.htm) 意思比较清晰,比如说,按照排列组合关系,大杯咖啡,小杯咖啡,和是否加奶,能够组成四种组合:大杯加奶,小杯加奶,大杯不加奶,小杯不加奶,如果再加一种行为进去,比如加巧克力,或者加方糖什么的,势必会出现更多的组合.如果为每一种组合创造一种对象,会造成对象过多代码混乱的状况. 还有很多例子阐述类似

reactor design pattern

详见:http://en.wikipedia.org/wiki/Reactor_pattern The reactor design pattern is ??an event handling pattern for handling service requests delivered(交付的)concurrently(并行的) to a service handler by one or more inputs. ??The service handler then demultiplex

Design Pattern Singleton 单一模式

单一模式的几个注意点: 一) 设计单一模式,首先需要把构造函数给私有化了,不让外界访问,那么外界只能通过提供的函数获取一个新的类. 二) C++的单一模式,记得要在类外初始化一个类,否则或内存出错的. 三) 这个唯一的类必须是要静态的 程序: #ifndef _SINGLETON_H #define _SINGLETON_H #include <iostream> #include <string> using namespace std; class DuGuJiuJian {

Head First Design Pattern 读书笔记(1) 策略模式

Head First Design Pattern 读书笔记(1) Strategy Pattern 策略模式 这几天为了锻炼看英语文档的能力,开着有道硬着头皮看 <Head First Desgin Pattern>的原版书,顺便做下笔记,把里面提到的每个模式通过回忆的方式画出来复习并记下来总结下学习成果=.= 关于设计模式 使用设计模式是为了增强程序的复用性,拓展性,易维护性. 设计模式会增加程序代码的复杂度,并不是所有情况都必须使用设计模式,需要根据需求以及经验评估使用场景. 学习并掌握

Head First Design Pattern 读书笔记(3)装饰者模式

Head First Design Pattern 读书笔记(3) Decorator Pattern 装饰者模式 Decorator Pattern 类图 定义 装饰者模式:通过让组件类与装饰者类实现相同的接口,装饰类可以在不修改原有组件类的情况下,动态拓展组件类的新功能,并且可以无限拓展下去. 几个OO的原测 类应该对修改关闭,对拓展开放.–>"开闭原则",即尽量不要修改已经在用的类,而通过继承的方式去拓展类的新功能. 设计类时应当尽量考虑不修改原有的代码.–>同&qu

Design Pattern Visitor 访问者模式

访问者模式,就是我们已经有一系列的对象了,那么就可以使用一个visitor对象一次性遍历所有的对象,就好像这个visitor访问了所有这些对象一样,所以就叫访问者模式. 实现起来也很简单,就是三个基类,其他类都是这些基类的衍生类. 下面的Action类就是访问者类了,而Person类就是被访问的对象类,而House是一个接待容器,可以接待不同的Action类. #include <stdio.h> #include <iostream> #include <string>

Design Pattern Chain of Reponsibility 责任链模式

本程序实现一个责任链模式查询人名的资料. 开始都是查询第一个人,问其是否有某人的资料,如果有就返回结果,如果没有第一个人就会询问第二个人,第二个人的行为和第一个人的行为一致的,然后一致传递下去,直到找到答案,或者是最后没有资料,返回. 首先创建一个基类: //base class class Person { public: virtual void getInfo(string name) = 0; }; 第一个人的类: 主要行为函数是getInfor,就是一个if else判断,这里使用ma

Design Pattern 设计模式 Decorator 装饰者模式

1 设计一个基类 2 继承这个基类,并包含这个基类的一个对象 3 创建继承类的时候,初始化这个基类,因为是基类指针,所以可以是所有基类的衍生类对象,那么就可以叠加任意多个衍生类对象了. 关键是在衍生类中包含一个基类对象,然后有了继承和包含两重关系,可以使得一个类一个类对象叠加,达到装饰目的. 等于是创建了一个对象指针链表,一个一个对象发挥其相应的作用. 下面程序装饰一个桌子,同时包含释放内存的处理. 关键要知道基类的析构函数必须使用虚函数,为什么? 1 如果基类不是析构函数,那么如果衍生类中包含

Mediator Design Pattern 中介者模式

就是设计一个Mediator类,可以处理其他类的关系. Mediator类: 1 拥有其他所有类的实例对象 2 设置一个接口供其他类使用,其他类也拥有一个Mediator类成员,只需调用这个Mediator接口函数使用,无需自己处理关系. 3 Mediator内部已经设置好各个类的关系了,其他类只要直接使用Mediator处理关系就可以了. 下面是一个聊天室聊天是处理关系的实例程序: 进入聊天室的人只需要选定和谁聊天就可以了,无需担心这些信息是如何传递的,这个已经由Mediator自动处理了.