Boost::Asio为同步和异步操作提供了并行支持,异步支持基于前摄器模式,这种模式的优点和缺点可能比只同步或反应器方法要低。
让我们检查一下Boost::Asio是如何实现前摄器模式的,没有引用基于平台的细节。
前摄器设计模式,改编自POSA2
--异步操作
定义一个异步执行的操作,比如socket的异步读和异步写。
--异步操作处理器
执行异步操作并在操作完成的时候把事件入队到一个完成事件队列,stream_socket_service等服务可以抽象成异步操作处理器。
--完成事件队列
缓存完成事件直到他们被异步事件分解器取出队列。
--完成句柄
处理异步操作的结果,是函数对象,经常使用boost::bind创建。
--异步事件多路分解器
阻塞等待完成事件队列,直到有事件发生,并返回一个完成事件给调用者。
--前摄器
调用异步事件分解器来把事件出队列,并且分发给同事件关联的完成句柄(调用函数对象),这个抽象层的代表是io_service层。
--发起者
应用程序的代码启动了异步操作,发起者通过一个抽象的接口来和异步操作处理器交互,比如basic_stream_socket,轮流提供类似于stream_socket_service的服务。
使用Reactor的实现
在许多平台,Boost::Asio依照Reactor的方式实现Proactor,比如select、epoll、kqueue,下列方法符合Proactor的设计模式:
--异步操作处理器
一个使用select、epoll、kqueue实现的Reactor,当Reactor指示资源已经准备好执行操作,处理器执行操作并把完成时间队列关联的完成句柄入队列。
--完成事件队列
完成句柄的列表(函数对象)。
--异步事件多路分解器
等待事件或者条件变量直到完成事件队列的完成句柄可用。
使用windows平台overlapped I/O实现
在windowsNT、2000或者xp,Boost::Asio利用overlapped的优势来实现有效的Protacor模式,下列是符合Proactor模式的方法:
--异步操作处理器
操作系统提供支持,通过调用AcceptEx之类的操作来发起操作。
--完成事件队列
操作系统提供支持,并和I/O完成端口关联起来,
--异步事件多路分解器
被Boost::Asio调用来出队列事件和他们的关联完成句柄。
优势
--可移植的
许多操作系统支持一个原生的异步I/O API作为高性能网络开发的推荐操作,这些库可能依据原生异步I/O的实现,然而,如果原生API不可用,这些库也可能使用典型Reactor模式的异步事件多路分解器来实现,比如POSIX select()。
--从并发中解耦线程
耗时长的操作被应用程序异步执行,因此应用程序不需要启动大量线程来提高并发
--性能和扩展性
某些实现策略会降低系统性能,比如每个线程一个连接,因为增加了CPU间的上下文切换、同步、数据移动,通过异步操作可以避免或者减少上下文切换开销-最小化操作系统的线程-限制资源-只激活有事件要处理的控制线程。
--简单的应用同步
异步完成句柄就像是在一个单线程环境写入,因此应用程序开发过程中可以少考虑或者不考虑同步问题。
--函数构成
函数构成依据函数的实现来提高更高抽象的操作,比如发送一个特定格式的消息,每个函数多次调用来完成较低抽象的读、写操作。
例如,一个协议的每个消息包含一个定长的消息头和变长的消息体,消息体的长度被消息头指定,一种假设是用两个低抽象的读、写操作完成消息的读取,第一个接收消息头,一旦消息长度确定,第二个接收整个消息。
为了写作异步模式的函数,异步操作可以被连接起来,也就是说,一个操作上的完成端口可以启动另外一个,启动链条的第一个可以被包装起来,调用者不需要知道高级抽象操作作为一个异步操作的链条来实现。
这种编写方式简化了开发者在网络库上的高层抽象,比如为了支持某种协议而开发函数。
劣势
--编程复杂性
使用异步模式开发应用程序更加困难,因为从时间和空间来看启动和完成被分割开来,因为控制流反转应用程序更难被调试。
--内存使用
在读、写期间内存是一直占用的,这会带来不确定性,在每个并发的时候需要一个单独的buffer,而Reactor模式,在读、写就绪前并不需要缓存空间。
参考文献
[POSA2] D. Schmidt et al, Pattern Oriented Software Architecture, Volume 2. Wiley, 2000. 

Proactor设计模式:单线程高并发的更多相关文章

  1. 协程--gevent模块(单线程高并发)

    先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...

  2. nodejs 单线程 高并发

    nodejs为什么是单线程且支持高并发的脚本语言呢? 1.node的优点:I/O密集型处理(node的I/O请求都是异步的,如:sql查询.文件流操作.http请求……):异步I/O?顾名思义就是异步 ...

  3. Node单线程高并发原理

    一.node是如何处理web请求的 浏览器中的js是单线程的,node也是单线程的.这个单线程相当于一个大管家,一切大小事务都要经过他的手才能办成,它总是把IO任务放入到任务池中. 虽然说是单线程,但 ...

  4. 理论铺垫:阻塞IO、非阻塞IO、IO多路复用/事件驱动IO(单线程高并发原理)、异步IO

    完全来自:http://www.cnblogs.com/alex3714/articles/5876749.html 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同 ...

  5. Redis 单线程却能支撑高并发 - 简书 https://www.jianshu.com/p/2d293482f272

    小结: 1.在 I/O 多路复用模型中,最重要的函数调用就是 select,该方法的能够同时监控多个文件描述符的可读可写情况:2.Redis 服务采用 Reactor 的方式来实现文件事件处理器(每一 ...

  6. 既然nodejs是单线程的,那么它怎么处理多请求高并发的?

    单线程解决高并发的思路就是采用非阻塞,异步编程的思想.简单概括就是当遇到非常耗时的IO操作时,采用非阻塞的方式,继续执行后面的代码,并且进入事件循环,当IO操作完成时,程序会被通知IO操作已经完成.主 ...

  7. Java进阶知识点:服务端高并发的基石 - NIO与Reactor AIO与Proactor

    一.背景 要提升服务器的并发处理能力,通常有两大方向的思路. 1.系统架构层面.比如负载均衡.多级缓存.单元化部署等等. 2.单节点优化层面.比如修复代码级别的性能Bug.JVM参数调优.IO优化等等 ...

  8. Java进阶知识点5:服务端高并发的基石 - NIO与Reactor模式以及AIO与Proactor模式

    一.背景 要提升服务器的并发处理能力,通常有两大方向的思路. 1.系统架构层面.比如负载均衡.多级缓存.单元化部署等等. 2.单节点优化层面.比如修复代码级别的性能Bug.JVM参数调优.IO优化等等 ...

  9. 为什么 redis 单线程却能支撑高并发

    redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 这个是问 redis 的时候,最基本的问题吧,redis 最基本的一个内部原理 ...

随机推荐

  1. css3的背景多重运用

    效果图: 简单代码: http://www.developerdrive.com/2013/08/introducing-css3-multiple-backgrounds/ 演示地址: http:/ ...

  2. UVa 12563 Jin Ge Jin Qu hao【01背包】

    题意:给出t秒时间,n首歌分别的时间a[i],还给出一首长度为678的必须唱的劲歌金曲,问最多能够唱多少首歌(只要最后时间还剩余一秒,都可以将劲歌金曲唱完) 用dp[i]代表花费i时间时唱的歌的最大数 ...

  3. asp.net 使用JQuery 调用Ashx 后面直接写方法名,通过反射找到对应的方法

    using System.Reflection; public class Industry_Manager : IHttpHandler { HttpRequest gRequest = null; ...

  4. 简单分析什么是SQL注入漏洞

    现在很多人在入侵的过程中基本都是通过SQL注入来完成的,但是有多少人知道为什么会有这样的注入漏洞呢?有的会随口说着对于字符的过滤不严造成的.但是事实是这样吗?我们学这些,不仅要知其然,更要知其所以然! ...

  5. QPS、PV和需要部署机器数量计算公式(转)

    术语说明: QPS = req/sec = 请求数/秒 [QPS计算PV和机器的方式] QPS统计方式 [一般使用 http_load 进行统计] QPS = 总请求数 / ( 进程总数 *   请求 ...

  6. DB2之隔离级别和锁的论述

    在DB2数据库中, 是通过行级锁和表级锁协调作用来提供较好的并发性, 同时保证数据库中数据的安全. 在DB2中缺省情况下使用行级锁(当然需要IS/IX锁配合),只有当出现锁资源不足, 或者是用命令指定 ...

  7. MySQL基础之第4章 MySQL数据类型

    4.1.整数类型 tinyint(4)smallint(6)mediumint(9)int(11)bigint(20) 注意:后面的是默认显示宽度,以int为例,占用的存储字节数是4个,即4*8=32 ...

  8. Conversion to Dalvik format failed: Unable to execute dex: null

    [2013-11-19 14:18:48 - Dex Loader] Unable to execute dex: java.nio.BufferOverflowException. Check th ...

  9. CABasicAnimation

    几个可以用来实现热门APP应用PATH中menu效果的几个方法 +(CABasicAnimation *)opacityForever_Animation:(float)time //永久闪烁的动画 ...

  10. 跟我学机器视觉-HALCON学习例程中文详解-FUZZY检测用于开关引脚测量

    跟我学机器视觉-HALCON学习例程中文详解-FUZZY检测用于开关引脚测量 * This example program demonstrates the basic usage of a fuzz ...