Blocking/Non-Blocking IO and SYN/ASYN IO

http://www.hzmangel.info/blog/archives/1035


ASYNC/SYNC 和 Blocking/Non-Blocking其实可以说是不相干的两个东西,但是由于使用的时候会有特定的组合,所以有时也就混为一谈了。分别在Internet和大中华局域网转了转,找到两篇文章[1][3],比着上次的幻灯小总结一下吧。

先从 Dai Jun 后来临时找的幻灯说起,那个片子把IO的时间分成了两个阶段,第一阶段是从应用程序发起请求开始到数据准备完毕结束,第二阶段是把数据从内核态拷贝到用户态。对于应用程序而言,当第二阶段结束后,就表示数据可以使用了,也就是这次IO操作完成。

首先说Blocking/Non-Blocking,阻塞和非阻塞的区别其实很简单,就是应用程序在等待数据的过程中,是否可以做其它的事情。例如最简单的SYN Blocking操作,程序调了个read()就后就把自己拍晕然后等着被返回的数据砸醒,晕了程序当然不能干活,所以它就是阻塞的。在文章[1]中,有几个很形象的示意图,可以很方便的看出区别。

再说说ASYN/SYN异步及同步,主要描述的是消息通知的机制([3]),同步SYN是指内核在处理完请求后,不会告诉程序数据已经准备好了,而需要程序自己去检查;而异步的情况下,请求处理完成后内核会发给程序一个通知。所以,对于悲催的Non-Blocking SYN的模式,程序需要一遍又一遍的去检查数据是不是好了,效率可能还没有Blocking SYN的高。而IO复用,即select()/epoll()的方案,虽然也有阻塞,但是终归它是由系统告知某个fd可用的,所以是异步的IO。至于AIO,把等待数据这个过程也省去了,直接发完请求该干嘛干嘛,等着被叫号就好了。

所以那天片子里面说的AIO,应该就是指Non-Blocking ASYN的情况,此文中下面写的AIO,都是指这种情况,即非阻塞异步IO。

说完了区别,再来给AIO补一点东西。

在Linux中,AIO有两种接口,一种是glibc提供的POSIX异步IO接口,即aio_*函数系;另一种是Linux的原生异步IO接口,是由libaio提供的。POSIX AIO是在用户空间通过线程+阻塞模拟并发操作来实现的,所以性能上没有太多出彩的地方,但是libaio是原生的AIO实现,性能上会好很多[2][4]。这个库好像最早是Oracle弄出来的,在Oracle/DB2中有应用。它使用不同于read()/write()的一套接口,具体的程序我也没看,不过应该是可以用在网络环境中的。

至于为什么现在还是用epoll撑起大半边天,可能是因为还没有到需要大规模考虑C1000K问题的时候吧,还有就是AIO的编程模型和传统模型的差别不是一点半点,基本上整个架构都需要推倒重来,相比于这个带来的风险,还是直接加服务器比较保险。不过TB已经有童鞋在折腾这些东西了,在slideshare上找到一个片子,有兴趣的可以去围观一下:

http://www.slideshare.net/mryufeng/c1000k 。话说,这个是不是丢给 Bergwolf 就好?

差不多就这些了,不知道有没有理解错的地方。最后是参考文献

[1] Boost application performance using asynchronous I/O, M. Tim Jones, http://www.ibm.com/developerworks/linux/library/l-async/

[2] Linux Asynchronous I/O Design: Evolution & Challenge, Suparna Bhattacharya,http://www.kernel.org/pub/linux/kernel/people/suparna/aio-linux.pdf

[3] 同步/异步与阻塞/非阻塞的区别, http://www.cppblog.com/converse/archive/2009/05/13/82879.html

[4] High Performance Solid State Storage Under Linux, Eric Seppanen, Matthew T. O’Keefe, David J. Lilja,http://storageconference.org/2010/Papers/MSST/Seppanen.pdf

Be Sociable, Share!

你可能感兴趣的:(Blocking/Non-Blocking IO and SYN/ASYN IO)