boost asio 对这些系统调用统一封装成proactor模型,通过io_service 类具体表达。
大多数网络编程的例子,是站在io处理的逻辑进行框架设计。一般是对io的处理进行重载或绑定,多半是handle_read handle_write handle_timeout等等的方式来实现。
有一些更高级的封装。如apache下的mina,是一个java的通讯框架,把io处理分解成protocol, io_handler,codec,filter等概念,首先把网络数据,通过codec转化为message,然后交给protocol处理。不多说了,有点跑题。
异步io的特色是io的触发和完成不是同步的,阻塞的,也就是触发io,并不知道io的结果,读写是否成功,多少个字节等等。
流水线编程是把把io的结果(一般封装成一个connection类)dispatch到一个线程池中,connection一直被一个流水线处理,从一端流动到另一端。状态的驱动一般是根据协议的逻辑。
流水线中的一个处理器可以设计为返回两个状态,1,0,1代表不需要等待异步io的结果而切换到下一个处理器,0可以代表需要读取异步io的结果再切换到下一个处理器。
流水线处理io的方式,将线程池中的线程和处理的应用逻辑进行分离。而且io读写时没有应用逻辑的代码。不需要锁什么的概念来同步资源。所以运行效率很高。
很多程序都是通过对列进行网络编程,线程有专门的角色,有的负责读,有的负责写,对列必然要进行多线程同步,而且最好还用读写锁,设置上下水线,防止队列上溢下溢。线程的效率因为同步,效率下降,而且线程被赋予专门的角色,专门的功能,浪费啊。
我讲的不好,举一个例子说明。
有一个connection类,包含一个buffer,这个buffer存放读写的数据和状态。
线程池运行一个循环函数,通过调用handle_events(ACE),run_once(ASIO),来驱动异步io。在完成异步io后,将connection放在一个全局的上下文对象,比如Map
效果:
线程池驱动网络io。线程没有绑定具体代码,公用。
io处理不需要锁同步,效率巨高。
将protocol的逻辑编入流水线,流水线就是一个状态机,编程逻辑简单。