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. Android之 学习路线

    第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环.  2.String和StringBuffer的使用.正则表达式.  3.面向对象的抽象,封装,继承,多态,类与对象,对象初 ...

  2. POJ 2942 Knights of the Round Table (点双连通分量)

    题意:多个骑士要开会,3人及以上才能凑一桌,其中部分人已经互相讨厌,肯定不坐在同一桌的相邻位置,而且一桌只能奇数个人才能开台.给出多个人的互相讨厌图,要求多少人开不成会(注:会议不要求同时进行,一个人 ...

  3. C语言深入学习系列 - 字节对齐&内存管理

    用C语言写程序时需要知道是大端模式还是小端模式. 所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中:所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高 ...

  4. 2013.11.15 初学ant构建

    该做的事情都差不多做完了,今天开始用ant构建,所以学了下ant,其实要不是因为ubuntu时不时的抽风我应该早就可以开始构建了,但重写的时候也想清楚了一些逻辑,优化了一些地方.下面是我这辈子写的第一 ...

  5. css清除浮动的两种方式(clearfix和clear)

    最近总是在用浮动,这两种方式总是浮现在眼前,或者说去掉父级和同级浮动样式总在思考中.两种方式怎么写都在base.css中. 在做瑞祥之旅的过程中,还是吃了一个大亏,就是清除浮动,不管是同级还是父级,都 ...

  6. 字符集编码Unicode ,gb2312 cp936

    这是一篇程序员写给程序员的趣味读物.所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级.整理这篇文章的动机是两个问题: 问题一:使用Windows记事本的“另存为” ...

  7. [Papers]NSE, $\p_3u$, Lebesgue space [Kukavica-Ziane, JMP, 2007]

    $$\bex \p_3\bbu\in L^p(0,T;L^q(\bbR^3)),\quad \frac{2}{p}+\frac{3}{q}=2,\quad \frac{9}{4}\leq q\leq ...

  8. C# 邮件发送系统

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  9. IOS UIScrollView中 使用 touch 无法响应的问题

    添加一个 Category  然后在使用到 UIScrollView 的文件里面 导入这个头文件 就可以 // //  UIScrollView+UITouch.m //  alarm // //  ...

  10. erp验收测试

    软件测试是为了发现错误而执行程序的过程.它不仅是软件开发阶段的有机组成部分,而且在整个软件工程(即软件定义.设计和开发过程)中占据相当大的比重.软件测试是软件质量保证的关键环节,直接影响着软件的质量评 ...