zoukankan      html  css  js  c++  java
  • Proactor设计模式:单线程高并发

    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. 
  • 相关阅读:
    Java进程线程理解
    Java String练习题及答案
    代理服务器原理(转)
    FTP服务器原理(转)
    SMTP协议及POP3协议-邮件发送和接收原理(转)
    集合框架的类和接口均在java.util包中。 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。
    Java集合框架顶层接口collectiion接口
    java多态--算法实现就是多态
    项目安排
    Scala从零開始:使用Intellij IDEA写hello world
  • 原文地址:https://www.cnblogs.com/learn-my-life/p/5268424.html
Copyright © 2011-2022 走看看