Boost.Asio库为同步操作和异步操作提供并行支持。异步操作支持基于Proactor设计模式。与同步操作或者Reactor方法相比较,这种方法的优点和缺点概述如下:

Proactor and Boost.Asio

让我们看看Proactor设计模式是如何在Boost.Asio库中实现的,不用参考平台相关细节。
Boost.Asio - The Proactor Design Pattern: Concurrency Without Threads

Proactor design pattern (adapted from [POSA2])

— Asynchronous Operation
定义一个异步执行的操作,例如在socket上的异步读写操作。
— Asynchronous Operation Processor
执行异步操作,并且在操作完成时将事件排队到一个完成事件队列。从更高层次看,像reactive_socket_service这样的内部服务就是异步操作处理器。
— Completion Event Queue
缓存完成事件,直到他们被异步事件信号分离器出队。
— Completion Handler
处理异步操作的结果。他是个函数对象,通常由boost::bind创建。
— Asynchronous Event Demultiplexer
在完成事件队列上阻塞等待事件发生,并且返回一个完成事件给它的调用者。
— Proactor
调用异步事件信号分离器来出队事件,并且递送给这个事件关联的completion handler。Proactor由io_context类来表示。
— Initiator
应用程序特定的开始异步操作的代码。这个initator与一个asynchronous operator processor交互,通过一个更高层次的接口,例如basic_stream_socket,basic_stream_socket转而委托一个service,像是reactive_socket_service。

Implementation Using Reactor

在许多平台上,Boost.Asio按照Reactor实现Proactor设计模式,例如select,epoll或者kqueue。这些实现方法对应于以下Proactor设计模式:
— Asynchronous Operation Processor
用select,epoll,kqueue实现reactor。当reactor代表的资源准备好执行操作时,processor执行异步操作,并且将关联的完成处理器排队到完成事件队列中。
— Completion Event Queue
一个包含完成处理器的链表。
— Asynchronous Event Demultiplexer
这被实现为,通过等待一个事件或条件变量,直到在完成事件队列上的一个完成处理器可用。

Implementation Using Windows Overlapped I/O

在Windows NT,2000,XP上,Boost.Asio采用重叠I/O来提供Proactor设计模式的高效实现。这个实现方法对应于以下Proactor设计模式:
— Asynchronous Operation Processor
这个被操作系统实现。这个操作是通过调用一个重叠函数例如AcceptEx被启动的。
— Completion Event Queue
这个被操作系统实现,并且被关联到一个I/O完成端口。每个io_context实例都有一个I/O完成端口。
— Asynchronous Event Demultiplexer
被Boost.Asio调用 ,用来出队事件和事件关联的完成处理器。

Advantages

— Portability.
很多操作系统都提供了一套本地异步I/O API(例如windows上的重叠I/O)作为开发高性能网络应用的首选选项。Boost.Asio可能会被按照本地异步I/O实现。然而,如果本地支持不可用,Boost.Asio可能会用synchronous event demultiplexors 来实现。
— Decoupling threading from concurrency.
长时间操作由代表应用程序的实现异步执行。因此应用程序不需要生成很多线程来提高并发性。
— Performance and scalability.
例如每个连接创建一个线程(仅同步方法需要如此)这样的实现策略会降低系统性能。由于CPU之间增加了上下文切换、同步和数据于东。对于异步操作,它就可能避免上下文切换的花销,通过最小化操作系统线程的数量 – 通常是有限的资源 – 并且只**有事件要处理的控制逻辑线程。
— Simplified application synchronisation.
异步操作完成处理器能被写成好像它存在于一个单独线程环境中一样,并且应用逻辑代码会更少,或者不用再关心同步问题。
— Function composition.
函数组合是指提供更高层次操作的函数实现,例如以特定格式发送信息。每个函数都是通过多次调用更低级的读写操作来实现的。

例如,考虑一个协议,其中每个消息由一个定长头以及紧随其后的一个变长的体,体的长度由头指定。一个假设的read_message操作能由使用两个较低级的读操作实现,第一个读取头,一旦长度可知,第二个就读取体。

为了在异步模式中组合函数,异步操作可以被链接到一起。也就是,一个操作的完成处理器能启动下一个异步操作。启动链中的第一个调用可以被封装,这样调用者就不必知道高级操作是作为异步操作链实现的。

以这种方式组合新操作的能力简化了网络库之上更高层次抽象的开发,例如支持特定协议的函数。

Disadvantages

— Program complexity.
由于操作的启动和完成在时间和空间上是分离的,因此使用异步机制开发应用程序更加困难。由于控制流倒置,应用程序可能更难调试。

— Memory usage.
必须在读或写操作期间提交缓冲区空间,这可能会无限期地继续,并且每个并发操作都需要一个单独的缓冲区。另一方面,Reactor模式在套接字准备好读写之前不需要缓冲区空间。

相关文章:

  • 2021-06-20
  • 2021-12-04
  • 2021-07-14
  • 2022-01-01
  • 2021-07-15
  • 2021-11-13
  • 2022-01-03
  • 2021-12-20
猜你喜欢
  • 2021-11-05
  • 2021-11-13
  • 2022-12-23
  • 2021-06-21
  • 2021-09-26
  • 2022-12-23
  • 2021-09-14
相关资源
相似解决方案