Asio 核心概念和功能文档学习(二)

前摄器(proactor)设计模式:没有线程的并发

Asio库同时提供对同步和异步操作的支持。异步操作的支持基于前摄器设计模型。这种方法与同步或反应器方法对比的优缺点列在下面。

 前摄器和Asio

不考虑平台相关细节,我们来检查一下前摄器设计模式在Asio中是如何实现的。

前摄器设计模式

Asynchronous Operation(异步操作)

定义一个异步执行的操作,例如socket的异步读写。

Asynchronous Operation Processor(异步操作处理器)

执行异步操作,并在操作完成时将事件放入完成事件队列。从高层的观点看,stream_socket_service之类的服务是asynchronous operation processors(异步操作处理器)。

Comletion Event Queue(完成事件队列)

缓存完成事件直到它们被asynchronous event demultiplexer(异步事件分离器)出列。

Completion Handler(完成处理程序)

处理异步操作的结果。它们通常是用boost::bind创建的函数对象。

Asynchronous Event Demultiplexer(异步事件分离器)

在完成事件队列上阻塞等待事件,并返回完成事件给调用者。

Proactor(前摄器)

调用Asynchronous event demultiplexer(异步事件分离器)出列事件,调度与事件相关的completion handler(完成处理程序)。被io_service类抽象表示。

Initiator(初始器)

启动异步操作的应用相关代码。初始器通过高层接口如basic_stream_socket与asynchronous operation processor(异步操作处理器)交互,它反过来代表像stream_socket_service的服务。

反应器实现

在很多平台上,Asio根据反应器实现前摄器设计模式,例如select,epoll或者kqueue。这种实现方法相应的前摄器设计模式如下:

Asynchronous Operation Processor(异步操作处理器)

用select,epoll或kqueue实现的一个反应器。当反应器表明执行操作的资源已经准备好了,处理器执行异步操作并且在相应的完成事件队列入队相应的完成处理程序。

Comletion Event Queue(完成事件队列)

完成处理程序的一个链接表。

Asynchronous Event Demultiplexer(异步事件分离器)

通过在一个事件或条件变量上等待实现,直到一个完成事件队列的完成处理函数可用。

用Windows Overlapped I/O实现

在Windows NT,2000和XP上,Asio利用overlappedI/O提供前摄器设计模式的高效实现。这种实现方式相应的前摄器设计模式如下:

Asynchronous Operation Processor(异步操作处理器)

由操作系统实现。调用重叠函数如AcceptEx初始化操作。

Comletion Event Queue(完成事件队列)

由操作系统实现,并结合一个I/O完成端口。每一个io_service实例都有一个I/O完成端口。

Asynchronous Event Demultiplexer(异步事件分离器)

由Asio调用出列事件和它们相应的完成处理程序。

优点

可移植

很多操作系统为开发高性能的网络应用提供一个原生的异步I/O API作为选项。库可以根据原生异步I/O实现。然而,如果没有原生支持,库也可以用典型的反应器模式的同步事件分离器实现,例如POSIX的select()。

从并发中解耦线程

持续时间长的操作被代表程序的实现异步执行。因此程序不需要产出很多线程来增加并发。

性能和可伸缩

因为增加的上下文切换,同步,和CPUs之间的数据移动等,每线程一个连接(同步方法会需要)的实现策略会降级系统的性能。异步操作通过最小化通常是有限资源的线程的数量避免上下文切换的花费,并只激活有事件要处理的控制逻辑线程。

简化程序同步

在一个单线程环境中可以写多个异步操作完成处理程序,因此程序逻辑开发可以很少或不用关心同步主题。

功能构成

功能构成指实现功能来提供高级操作,如以一个特殊的格式发送一个消息。多个低级的读写操作的调用实现每一个功能。

例如,考虑一个每个消息由固定长度的头跟着可变长度的体的协议,体的长度是在头中指定的。一个假的读消息操作用两个低级的读实现,第一个接收头,知道长度后,第二个接收体。

在异步模型中编写功能,异步操作能被链在一起。也就是,一个操作的完成处理程序能初始下一个操作。开始调用能被链中的第一个操作封装,所以调用者不需要知道高级操作是被一串异步操作实现的。

这种构成新操作的能力简化了在网络库之上的高级抽象开发,例如支持特定协议的功能。

缺点

程序复杂

用异步机制开发应用是更难的,因为在操作初始化和完成之间的时间和空间是分离的。由于颠倒的控制流程序可能也很难被调试。

内存使用

必须保证可能无限持续下去的读写操作期间的缓存空间,并且需要为每一个并发的操作提供单独的缓存。另一方面,直到一个socket准备好读写前,反应器模式不需要缓存空间。

 

posted @ 2012-08-21 00:24  国超  阅读(591)  评论(0编辑  收藏  举报