红联Linux门户
Linux帮助

异步IO与流水线编程

发布时间:2008-08-20 20:43:14来源:红联作者:dzajk
windows 完成端口,linux epoll,freebsd keyqueue,solaris aio,对io的处理方式有很多特色。

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 。然后利用这个上下文对象,得到connection对象,再进行流水线处理。循环往复。

效果:

线程池驱动网络io。线程没有绑定具体代码,公用。

io处理不需要锁同步,效率巨高。

将protocol的逻辑编入流水线,流水线就是一个状态机,编程逻辑简单。
文章评论

共有 0 条评论