课二:前摄器设计模式(不使用多线程并发)

Asio库为同步和异步提供一一对应的操作。异步支持是基于前摄器设计模式。该模式的优势和劣势将在下面说明,与之对应的是反射器模式,该模式是一种同步模式。

前摄器的实现:

在Asio库中,前摄器的实现方式如下,该实现方式跨平台一致。

前摄器设计模式:

一、异步操作

  定义一个异步执行的操作,例如在一个套接字上进行异步的读写。

二、异步操作处理

  执行异步操作并当操作结束时,执行事件完成队列上的某个事件。从更高的层次看,如    stream_socket_service 这样的服务均是异步操作处理器。

三、事件完成队列

  存储完成事件,直到这些事件出队,通过异步事件分离器将会引导事件的出队。

四、完成处理函数

  处理函数用于处理异步操作的返回结果。均为函数对象,采用boost::bind来实现。

五、异步事件分离器

  异步事件分离器将会阻塞等待异步完成事件队列产生新的事件,并且返回一个已完成的事件给调用方。

六、前摄器

  调用异步事件分离器使事件出队,并注册事件处理函数。该抽象设计典型代表类如io_service。

七、调用方

  由应用程序调用方开始异步操作。调用方通过上层接口如basic_stream_socket同异步操作处理器交互,

而上层接口反过来委托一个服务如stream_socket_service来处理交互。

反射器的实现:

很多平台,Asio库以反射器的方式来实现前摄器的设计模式,例如select、epoll或kqueue等I/O复用函数。这些

实现与前摄器设计模式相近的地方如下:

一、 异步操作处理器

  反射器的实现采用select、epoll或kequeue等函数。当一个反射器表明某资源已经准备执行操作时,处理器执行异步操作并且将相关的完成事件处理函数插入完成事件队列中。

二、完成事件队列

  完成事件队列为多个处理完成事件的回调函数构成的链表。

三、异步事件分离器

  异步事件分离器实现的方式是通过等待某一事件的发生或条件变量的变化且可以获取完成事件处理函数。

windows系统重写I/O操作

在Window NT,2000和XP操作系统上,Asio库利用重载I/O的方式来提供一种有效的前摄器实现。这种实现的模式

大致如下:

一、 异步操作处理器

  这个过程由操作系统实现,各类操作由重载函数来初始化,重载函数如AceptEx。

二、完成事件队列

  该实现由操作系统来完成,并且同I/O端口有关,对于每个io_service实例,都存在一种I/O完成端口。

三、异步事件分离器

  由Asio调用来进行事件出队操作,这些事件都与事件处理函数绑定。

优势:

一、可移植性。

  许多操作系统提供原生的异步I/O接口(如windows上面的I/O重载接口),这些I/O接口可能以原生异步I/O来实现。然而,如果原生支持不可用,这些异步库可采用同步事件分离器来实现,作为一种典型反射器应用,如

POSIX select函数。

二、并发多线程

  长持续时间的操作表现出异步操作性,一个应用程序就是典型代表。因此,应用程序不需要调用太多线程来增加并发性。

三、性能和可伸缩性

  采用每个线程处理一个连接的方式将会降低系统性能,这主要是因为增加了上下文的切换,同步处理和数据迁移。采用异步操作为避免上下文切换消耗,通过最小化操作系统线程数且只激活处理事件的逻辑线程。

  

时间: 2024-12-21 13:46:27

课二:前摄器设计模式(不使用多线程并发)的相关文章

设计模式-前摄器模式(Proactor)

本周要进行boost asio库的学习,在学习之前发现最好需要先了解一下前摄器模式,这样对asio库的理解很有帮助,故写下此文 我之前写的随笔XShell的模拟实现中的链接方式可以说是同步的(服务器阻塞等待链接),这样当有服务器端在等待链接的时候就浪费了大量的资源,我们可以让服务器异步等待客户端的链接,服务器在等待链接的同时可以做别的事情,等到客户端链接请求到来的时候,调用一个回调执行链接,这就很灵活. 先来一段关于前摄器模式的官话:前摄器模式支持多个事件处理器的多路分离和分派,这些处理器由异步

asio的前摄器模式

设计模式-前摄器模式(Proactor 先来一段关于前摄器模式的官话:前摄器模式支持多个事件处理器的多路分离和分派,这些处理器由异步事件的完成来触发.通过集成完成事件(completion event)的多路分离和相应的事件处理器的分派,该模式简化了异步应用的开发. 简单点说,前摄器的实现多亏了多个事件处理器将事件和处理分离开,和处理方式的分派.而这些事件处理器的的触发方式是当被异步事件(仅限完成事件)通知而出发的.把这些个东西搞在一起就是前摄器模式了. 前摄器(proactor)模式 前摄器模

第三十四课 二维数组的存储 【项目1-3】

第三十四课 二维数组的存储 项目一[二维数组当函数参数] 定义一个函数来完成对参数数组中元素的求和工作,函数声明如下: [cpp] view plain copy print? int sum(int array[ ][4],int m,int n);  //该函数完成对array数组中的前m行和n列元素求和 在以下程序的基础上,完成对sum函数的定义. [cpp] view plain copy print? #include <stdio.h> int sum(int array[ ][4

第三十二课 二维数组及其定义 【项目1-2】

第三十二课  二维数组及其定义 项目一 [折腾二维数组] 创建一个5行4列的二维整型数组,通过初始化,为数组中的前两列的10个元素赋初值,然后: 通过键盘输入,使后两列的10个元素获得值: 按行序优先输出数组元素: 将所有元素值乘以3后保存在数组中: 按列序优先输出(输出的第一行是数组中的第一列--,其实输出的就是"转置"): 将数组"倒"着输出(即最后一行最后一列的最先输出,第0行第0列的最后输出): 输出数组中的所有偶数: 输出所有行列下标之和为3的倍数的元素值

Python小程序练习二之装饰器小例子

Python小程序练习二之装饰器小例子 装饰器: 装饰器实际上就是为了给某程序增添功能,但该程序已经上线或已经被使用,那么就不能大批量的修改源代码,这样是不科学的也是不现实的,因为就产生了装饰器,使得其满足: 1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 那么根据需求,同时满足了这两点原则,这才是我们的目的. 装饰器的原则组成: < 函数+实参高阶函数+返回值高阶函数+嵌套函数+语法糖 = 装饰器 > 错误例子: 1.1Decorators.py 1 # The aut

二、模版方法设计模式

模板方法设计模式: 解决的问题:当功能内部一部分实现是确定,一部分实现是不确定的.这时可以把不确定的部分暴露出去,让子类去实现. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 abstract class GetTime{     public final void getTime(){ //此功能如果不需要复写,可加final限定         long start

【ThinkingInJava】42、装饰器设计模式

/** * 书本:<Thinking In Java> * 功能:装饰器设计模式 * 装饰器模式使用分层对象来动态透明的向单个对象添加责任.装饰器指定包装在最初的对象周围的所有对象都具有相同的基本接口 * 某些事物是可装饰的,可以通过将其他类包装在这个可装饰对象的四周,来将功能分层. * 装饰器是通过使用组合和形式化结构(可装饰物/装饰器层次结构)来实现的,而混型是基于继承的 * 文件:Decoration.java * 时间:2015年4月21日10:18:43 * 作者:cutter_po

装饰器设计模式初探(Java实现)

本篇随笔主要介绍用Java实现简单的装饰器设计模式: 先来看一下装饰器设计模式的类图:  从图中可以看到,我们可以装饰Component接口的任何实现类,而这些实现类也包括了装饰器本身,装饰器本身也可以再被装饰. 下面是用Java实现的简单的装饰器设计模式,提供的是从基本的加入咖啡入手,可以继续加入牛奶,巧克力,糖的装饰器系统. 1 interface Component { 2 void method(); 3 } 4 class Coffee implements Component { 5

【three.js详解之二】渲染器篇

[three.js详解之二]渲染器篇 本篇文章将详细讲解three.js中渲染器(renderer)的设置方法. three.js文档中渲染器的分支如下: Renderers CanvasRenderer DOMRenderer SVGRenderer WebGLRenderer WebGLRenderTarget WebGLRenderTargetCube WebGLShaders 可以看到three.js提供了很多的渲染方式,我们选择的当然是WebGLRenderer,但我们这里要将Canv