Asio The Proactor Design Pattern: Concurrency Without Threads

Proactor 设计模式:没有线程的并发

Asio库提供同步和异步操作的并行支持(side-by-side support)。异步支持基于Proactor设计模式。与仅同步或者Reactor方法相比,异步的优缺点概述如下:

Proactor和Asio

让我们看看Proactor设计模式在Asio中是如何实现的,而不参考特定于平台的细节。
在这里插入图片描述

Proactor设计模式
  • 异步操作(Asynchronous Operation)
    • 定义异步执行的操作,例如对套接字的异步读写
  • 异步操作处理器(Asynchronous Operation Processor)
    • 当操作完成时执行异步操作,并将事件加入完成事件队列。 从高层角度看,reactive_socket_service这样的内部服务是异步操作处理器。
  • 完成事件队列(Completion Event Queue)
    • 缓冲完成事件,直到它们被异步事件分离器出队列
  • 完成处理程序(Completion Handler)
    • 处理异步操作的结果。是函数对象,通常用boost::bind构造
  • 异步事件分离器(Asynchronous Event Demultiplexer)
    • 阻塞等待发生在完成事件队列上的事件,并将它们返回给它的调用者
  • Proactor
    • 调用异步事件分离器将事件出队列,并分发给与事件关联的完成处理程序。这种抽象由io_context类表示
  • 发起者(Initiator)
    • 开始异步操作的特定应用程序代码。发起者通过basic_stream_socket这样的高层接口与一个异步操作处理器交互。该接口又委托给reactive_socket_service这样的服务。
使用reactor实现

在很多平台,Asio借助Reactor实现Proactor设计模式,例如select、epoll或kqueue。这种实现方式对应于上述的Proactor设计模式如下:

  • 异步操作处理器(Asynchronous Operation Processor)
    • 由select、epoll或kqueue实现的reactor。当reactor指示资源准备好执行操作时,处理器执行异步操作并将关联的完成处理程序加入完成事件队列中
  • 完成事件队列(Completion Event Queue)
    • 完成处理程序的链表
  • 异步事件分离器(Asynchronous Event Demultiplexer)
    • 通过等待事件或者条件变量实现,直到完成事件队列中的一个完成处理程序可用
使用Windows Overlapped I/O实现

在 Windows NT、2000 和 XP 上,Asio 利用Overlapped I/O 来提供 Proactor 设计模式的有效实现。这种实现方式对应于 Proactor 设计模式如下:

  • 异步操作处理器(Asynchronous Operation Processor)
    • 这是由操作系统实现的。操作是通过调用重叠函数例如AcceptEx来启动的
  • 完成事件队列(Completion Event Queue)
    • 这是由操作系统实现的,并与 I/O 完成端口相关联。每个io_context实例都有一个 I/O 完成端口。
  • 异步事件分离器(Asynchronous Event Demultiplexer)
    • 由 Asio 调用以使事件及其关联的完成处理程序出队
优点
  • 可移植性(Portability)
    • 许多操作系统提供本地异步 I/O API(例如Windows上的Overlapped I/O )作为开发高性能网络应用程序的首选选项。该库可以根据本机异步 I/O 来实现。但是,如果本地支持不可用,也可以使用典型的 Reactor 模式例如POSIX select()的同步事件分离器来实现
  • 将线程与并发分离(Decoupling threading from concurrency)
    • 长时间操作由代表应用程序的实现异步执行。因此,应用程序不需要产生许多线程来增加并发性。
  • 性能和可扩展性(Performance and scalability)
    • 由于增加了 CPU 之间的上下文切换、同步和数据移动,诸如每个连接一个线程(仅同步方法需要)等实现策略会降低系统性能。使用异步操作,可以通过最小化操作系统线程的数量(通常是有限的资源)并仅激活有事件要处理的逻辑控制线程来避免上下文切换的成本。
  • 简化应用程序同步(Simplified application synchronisation)
    • 可以编写异步操作完成处理程序,就好像它们存在于单线程环境中一样,因此可以在应用程序逻辑开发过程中很少或不考虑同步问题
  • 功能组合(Function composition)
    • 功能组合是指实现功能以提供更高级别的操作,例如以特定格式发送消息。每个功能都是根据对较低级别的读写操作的多次调用来实现的
    • 例如,考虑一个协议,其中每条消息都由一个固定长度的标头和一个可变长度的正文组成,其中正文的长度在标头中指定。一个假设的 read_message 操作可以使用两个较低级别的读取来实现,第一个接收头,一旦长度已知,第二个接收正文。
    • 要在异步模型中组合功能,可以将异步操作链接在一起。也就是说,一个操作的完成处理程序可以启动下一个操作。可以封装启动链中的第一个调用以便调用者不需要知道更高级别的操作是由异步操作链实现的。
    • 以这种方式组合新操作的能力简化了网络库之上更高层次抽象的开发,例如支持特定协议的功能。
缺点
  • 程序复杂性
    • 由于操作启动和完成之间的时间和空间分离,使用异步机制开发应用程序更加困难。由于反向的控制流,应用程序也可能更难调试
  • 内存使用情况
    • 在读取或写入操作期间必须提交缓冲区空间,并可能会无限期地继续,而且每个并发操作都需要一个单独的缓冲区。另一方面,Reactor 模式在套接字准备好读取或写入之前不需要缓冲区空间。
原文

The Proactor Design Pattern: Concurrency Without Threads

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值