The Practor Design Pattern: Concurrency Without Threads
无需使用线程实现并发的设计模式--- 前摄器设计模式
The Boost.Asio library offers side-by-side support for synchronous and asynchronous operations.
Boost.Asio 函数库中同时提供同步和异步操作机制.
The asynchronous support is based on the Proactor design pattern.
其中的异步机制是基于前摄器设计模式思想而实现的.
The advantages and disadvantages of this approach, when compared to a synchronous-only or Reactor approach, are outlined below.
该(基于前摄器设计模式思想)解决方法 同 纯同步运行机制 或是,基于"反应堆"设计模式思想的解决方法的 优缺点对比分析将会在下面给出概述.
Proactor and Boost.Asio
前摄器与Boost.Asio 库
Let us examine how the Proactor design pattern is implemented in Boost.Asio,without reference to paltform-specific details.
让我们来检测一下, 在不考虑不同型号的系统平台的特殊细节差异这一前提下,在 Boost.Asio 函数库中如何将Proactor(前摄器)这一设计模式进行实例化的
(此实例化指的是,将设计模式思想应用与库函数的编程中)
Proactor design pattern( adapted from [POSA2] )
前摄器设计模式 (改编自 [面向模式软件架构] 一书)
---- Asynchronous Operation
---- 异步 操作
| Defines an operation that is executed asynchronuously ,such as an asynchronous read or write on a socket
|定义一种可以异步执行的操作,像是 在套接字上异步执行的读或是写操作.
---- Asynchronous Operation Processor
---- 异步操作处理程序
| Executes asynchronous operations and queues events on a completion event queue when operations complete .
| (所谓的 异步操作处理器 指的便是用于 )执行异步操作,且当操作结束之后,响应并处理 缓存于完成事件队列 中的队列事件.
| From a high-level point of view, services like stream_socket_service are asynchronous operation processors.
| 从高级别的程序设计角度来分析, 诸如, 流式套接字服务 这样的服务(执行流程)都是符合 异步操作处理程序/器的定义.
---- Completion Event Queue
---- 完成事件队列
| Buffers completion events until they are dequeued by an asynchronous event demultiplexer
| (所谓的 完成事件队列 指的是)用于临时存放完成事件的缓冲区,直到异步事件多路分配器将等待事件从缓冲队列中取出.
---- Completion Handler
---- (事件执行) 完成句柄
| Processes the result of an asynchronous operation . These are function objects, often created using boost::bind()
| (该句柄) 用作处理 一项异步操作结束之后所得到的结果对象. 处理的大多是通过调用 boost::bind() 而创建的方法对象.
---- Proactor
---- 前摄器
| Calls the asynchronous event demultiplexer to dequeue events, and dispatches the completion handler (i.e. invokes the function object ) associated with the event .
| 通过调用异步事件多路分配器将队列中的事件(对象) 取出,并且将事件分发给与之相关的事件完成句柄(完成句柄,也就是用于触发方法实体执行,
| 不同的事件绑定到不同的句柄上面,触发执行不同的方法)
| This abstraction is represented by the io_service class .
| 上述抽象概念,在 Boost.Asio 函数库中以 io_service 类所呈现.
---- Initiator
---- 启动器
| Application-specific code that starts asynchronous operations.
| 启动器是针对发起特定应用程序的异步操作执行的代码./ 启动器时一段代码, 该代码用于启动特定程序中的异步操作
| The Initiator interacts with an asynchronous operation processor via a high-level interface such as basic_stream_socket,
| which in turn delegates to a service like stream_socket_service.
| 启动器通过像是, basic_stream_socket 这样高级别的接口来于异步执行处理器相交互, basic_stream_socket 与 stream_socket_service 相仿,它们都可以实现轮流委托这样的服务.
Implementation Using Reactor
基于反应堆模式实现(异步操作)
On many platforms , Boost.Asio implements the Proactor design pattern in terms of a Reactor, such as select, epoll or kqueue.
在很多平台中, Boost.Asio 函数库是依据 select,epoll 或是 kqueue 这类基于"反应堆"设计思想来实现前摄器设计思想理念的.
This implementation approach corresponds to the Proactor design pattern as follows:
在"前摄器"设计模式中使用到"反映堆" 设计模式的思想解决方法陈列如下:
---- Asynchronous Operation Processor
---- 异步操作处理器
| A reactor implemented using select ,epoll or kqueue. When the reactor indicates that the resource is ready to perform the operation,
| the processor executes the asynchronous operation and enqueues the associated completion handler on the completion event queue.
| "反映堆"设计模式中的异步操作处理器/程序 是借助于 select ,epoll 或是 kqueue 这样的系统调用来实现的. 当反应器明确指示它已经具备执行操作所需的资源的时,
| 处理器将会异步的执行操作,并将相关联的完成句柄 “入队” ---- 存放到完成事件队列中去.
---- Completion Event Queue
---- 完成 事件 队列
| A linked list of completion handlers (i.e. function objects).
| 用于存放完成句柄对象(也就是,方法对象实例)的链表
---- Asynchronous Event Demultiplexer
---- 异步事件多路分配器
| This is implemented by waiting on an event or condition variable until a completion handler is available in the completion event queue.
| 异步事件多路分配器的实现是,通过,等待事件的发生或是条件变量的变化,直到获得完成队列中的某个完成句柄为止.
Implementation Using Windows Overlapped I/O
通过使用 Windows 中的"Overlapped I/O" 异步读写方法来实现异步操作
On Windows NT,2000, and XP , Boost.Asio takes advantage of overlapped I/O to provide an efficient implementaion of the Proactor design pattern.
Boost.Asio 因地制宜地使用了 Windows NT, 2000 和 XP 操作系统中原生的异步读写方法(overlapped I/O 异步读写操作),将其(原生异步读写操作方法)有效的应用于Proactor(前摄器)设计模式的实现中。
This implementation approach corresponds to the Proactor design pattern as follows :
在实现过程中所牵涉有关前摄器设计模式的相关概念如下:
---- Asychronous Operation Processor
---- 异步操作处理器
| This is implemented by the operating system. Operations are initated by calling an overlapped function such as AcceptEx.
| 该组件已在操作系统中被实现了. 通过调用像是 AcceptEx 这类异步方法便可触发异步操作的执行.
---- Completion Event Queue
---- 完成事件队列
| This is implemented by the operating system, and is associated with an I/O completion port . There is one I/O completion port for each io_service instance .
| 完成时间队列也已经在操作系统中被实现了,并且它与系统中的完成端口是有所关联的. io_service 对象实例与完成端口二者是一一映射的关系.
---- Asychrounous Event Demultiplexer
---- 异步事件多路分配器
| Called by Boost.Asio to dequeue events and their associated completion handlers.
| 这个异步事件多路分配器是用来被 Boost.Asio 函数库调用,目的是将(完成队列中的)事件和其相关的句柄从队列中取出来.
Advantages
优势
---- Protability
---- 可移植性
| Many operating systems offer a native asychronous I/O API (such as overlapped I/O Windows) as the preferred option for developing high performance network applications.
| 许多操作系统提供了原生的异步读写操作应用程序接口(比如说,Windows 系列的操作系统中的 'overlapped' 异步操作方法) 作为编写高性能网络应用程序的首选方法.
| The library may be implemented in terms of native asynchronous I/O .
| 库函数的设计可遵照原生异步读写操作接口.
| However , if native support is not available , the library may also be implemented using synchronous event demultiplexors that typify the Reactor pattern,
| such as POSIX select () .
| 然而,如果在本机中不支持异步读写操作的话,那么函数库也可以通过使用同步事件多路分配器来实现异步读写功能,同步事件多路分配器比较典型的代表模型就是
| “反应堆” 设计模式,像可移植性操作系统接口中的 select() 方法的设计便是遵循了 "反应堆"这一设计模式的.
---- Decoupling threading from concurrency.
---- 将并发操作与线程相分离
| Long-duration operations are performed asynchronously by the implementation on behalf of the application.
| 代表应用程序的实例化,可以异步地执行具有 长期-持续性 的操作。
/ 妈妈,这句是我编的,妈妈,我编不下去了.....,
/ 我只知道 implementation on behalf of the application 是主语
/ 同义句是 : The implementation on behalf of the application performed long-duration operations asynchronously.
| Consequently applications do not need to spawn many threads in order to increase concurrency.
| 因此,该应用程序无需为了增加并行度创建大量的线程.
---- Performance and scalability
| Implementation strategies such as thread-per-connection( which as synchronous-only approach would require) can degrade system performance,
| due to increased context switching, synchronisation and data movement among CPUs.
| 在编程中,实现了将一个线程实例对应一个连接的设计策略的话(这种策略只能通过 纯粹的同步处理方法来解决) (而纯粹的同步机制)
| 会增加CPU中(中央处理器)的上下文切换, 同步处理调度和数据传送的频度,从而降级系统性能。
| With asynchronous operations it is possible to avoid the cost of context switching by minimising the number of operating system threads
| -- typically a limited resources -- and only activating the logical threads of control that have events to process.
| 如果使用异步操作设计策略的话,可以将操作系统中运行的线程数目降到最低, 从而避免CPU中上下文切换所损耗的系统资源,
| --线程我们都知道,它是操作系统中典型的受限资源-- . 使用异步设计策略还可以实现仅让用于控制事件运行的逻辑线程保持活跃状态.
---- Simplified application synchronisation
---- 简化应用程序同步处理机制
| Asynchronous operation completion handlers can be written as though they exist in a single-threaded environment ,
| and so application logic can be developed with the little or no concern for synchronisation issues.
| 异步操作下的完成句柄是可以被改写的,就像是该完成句柄运行与当线程环境下一样,
| 这样一来,再设计异步化的应用程序逻辑时,可以极少或是根本无需关注,在同步处理机制中所需要注意的问题./问题: 加锁解锁,死锁,临界资源的访问限制.....
---- Function composition.
---- 完成方法对象
| Function composition refers to the implementation of functions to provide a higher-level operation, such as sending a message in a particular format.
| 完成方法对象值得是用于提供更高级别的处理而实现的方法实例,像是发送特殊格式的信息.
| Each function is implemented in terms of multiple calls to lower-level read or write operations.
| 每个方法是依照着多次调用低级别的读或写操作而被(设计与)实现的.
| For example, consider a protocol where each message consists of a fixed-length header followed by a variable length body,
| where the length of the body is specified in the header.
| 举例说明一下,有这样一个协议,在协议中每条消息都是有固定-长度的信息头部和其后面长度可变的信息体所构成的,
| 该长度可变的信息体的长度被记录在信息头中.
| A hypothetical read_message operation could be implemented using two lower-level reads,
| the first to receive the header and , once the length is known , the second to receive the body.
| 这里我们假设 read_message 方法可以通过调用比起本身要低端的两个读操作方法来实现,
| 第一个低端读操作方法用于接收消息头,且一旦通过消息头获知了消息体的长度,便调用第二个低端读操作来接收消息体.
| The compose functions in an asynchronous model , asynchronous operations can be chained together.
| 遵照异步模型中的"方法合成"这一思想,异步操作是可以被链接在一起的.
| That is , a completion handler for one operation can initiate the next.
| 这就是为何,一个操作的完成句柄可以用来启动下一个操作的原因.
| Starting the first call in the chain can be encapsulated so that the caller need not be aware that the higher-level operation is implemented as a chain of asynchronous operations.
| 启动异步操作链条中的首个调用方法将会被其他方法所封装调用,因为了该调用方法无需知道,异步操作链中的高级别操作是如何(在封装并调用它的基础上而)被实现的.
| The ability to compose new operations in this way simplifies the developement of higher levels of abstraction above a networking library, such as functions to support a specific protocol.
| 通过使用 (将旧方法)组装成新方法这一手段,可以极大的简化 在原有网络库函数之上开发出具有更高抽象程度的函数库的难度,比如说,(基于原有的网络函数库)开发出来支持特定协议的方法.
Disadvantages
劣势
---- Program complexity
---- 编程复杂度
| It is more difficult to develop applications using asynchronous mechanisms due to the separation in time and space between operation initiation and completion.
| 使用异步编程机制,由于在异步操作的启动和完成操作这一过程中脱离了与时间、空间的关联,这将会使得编写应用程序变得更加的复杂.
/ 这个地方就是说,异步编程的思想是事件驱动触发异步操作的,而事件驱动的顺序既不是按照时间发生先后的顺序(时间顺序),
/也不是按照异步链中事件排列的顺序(空间顺序)进行的,所以在思考方式上不能够以时间顺序或是空间顺序作为参考,作为参考的对象应该是状态机.
| Applications may also be harder to debug due the the inverted flow of control .
| 应用程序的调试也会由于控制流的翻转而变得更加的困难.
---- Message usage.
---- 消息的使用
| Buffer space must be committed for the duration of a reader or write operation, which may continue indefinitely , and a seperate buffer is required for each concurrent operation.
| 缓冲区必须持续的被不定期执行读写操作所使用,每个并行的操作需要的缓冲区必须要和其他缓冲区相分隔开.
| The Reactor pattern , on the other hand , does not require buffer space until a socket is ready for reading or writing .
| “反应堆” 模式,从另一个角度来说,直到套接字准备执行读写操作的之前,都是无需使用缓冲空间的.
References
参考资料
[POSA2] D. Schmidt et al, Pattern Oriented Software Architecture,
Volume 2. Wiley, 2000.
阅读(1374) | 评论(0) | 转发(0) |