课二:前摄器设计模式(不使用多线程并发)
Asio库为同步和异步提供一一对应的操作。异步支持是基于前摄器设计模式。该模式的优势和劣势将在下面说明,与之对应的是反射器模式,该模式是一种同步模式。
前摄器的实现:
在Asio库中,前摄器的实现方式如下,该实现方式跨平台一致。
前摄器设计模式:
一、异步操作
定义一个异步执行的操作,例如在一个套接字上进行异步的读写。
二、异步操作处理
执行异步操作并当操作结束时,执行事件完成队列上的某个事件。从更高的层次看,如 stream_socket_service 这样的服务均是异步操作处理器。
三、事件完成队列
存储完成事件,直到这些事件出队,通过异步事件分离器将会引导事件的出队。
四、完成处理函数
处理函数用于处理异步操作的返回结果。均为函数对象,采用boost::bind来实现。
五、异步事件分离器
异步事件分离器将会阻塞等待异步完成事件队列产生新的事件,并且返回一个已完成的事件给调用方。
六、前摄器
调用异步事件分离器使事件出队,并注册事件处理函数。该抽象设计典型代表类如io_service。
七、调用方
由应用程序调用方开始异步操作。调用方通过上层接口如basic_stream_socket同异步操作处理器交互,
而上层接口反过来委托一个服务如stream_socket_service来处理交互。
反射器的实现:
很多平台,Asio库以反射器的方式来实现前摄器的设计模式,例如select、epoll或kqueue等I/O复用函数。这些
实现与前摄器设计模式相近的地方如下:
一、 异步操作处理器
反射器的实现采用select、epoll或kequeue等函数。当一个反射器表明某资源已经准备执行操作时,处理器执行异步操作并且将相关的完成事件处理函数插入完成事件队列中。
二、完成事件队列
完成事件队列为多个处理完成事件的回调函数构成的链表。
三、异步事件分离器
异步事件分离器实现的方式是通过等待某一事件的发生或条件变量的变化且可以获取完成事件处理函数。
windows系统重写I/O操作
在Window NT,2000和XP操作系统上,Asio库利用重载I/O的方式来提供一种有效的前摄器实现。这种实现的模式
大致如下:
一、 异步操作处理器
这个过程由操作系统实现,各类操作由重载函数来初始化,重载函数如AceptEx。
二、完成事件队列
该实现由操作系统来完成,并且同I/O端口有关,对于每个io_service实例,都存在一种I/O完成端口。
三、异步事件分离器
由Asio调用来进行事件出队操作,这些事件都与事件处理函数绑定。
优势:
一、可移植性。
许多操作系统提供原生的异步I/O接口(如windows上面的I/O重载接口),这些I/O接口可能以原生异步I/O来实现。然而,如果原生支持不可用,这些异步库可采用同步事件分离器来实现,作为一种典型反射器应用,如
POSIX select函数。
二、并发多线程
长持续时间的操作表现出异步操作性,一个应用程序就是典型代表。因此,应用程序不需要调用太多线程来增加并发性。
三、性能和可伸缩性
采用每个线程处理一个连接的方式将会降低系统性能,这主要是因为增加了上下文的切换,同步处理和数据迁移。采用异步操作为避免上下文切换消耗,通过最小化操作系统线程数且只激活处理事件的逻辑线程。