AIO的实际意义在什么地方? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
funcman
V2EX    问与答

AIO的实际意义在什么地方?

  funcman 2011-12-06 16:06:27 +08:00 6281 次点击
这是一个创建于 5063 天前的主题,其中的信息可能已经有所发展或是发生改变。
我们在解决高性能并发问题时有两个并发模型:Reactor和Proactor。
对于用户(相对系统来说),Reactor意味着系统提供一个通知机制,实际的IO由用户来做。
而Proactor意味着,用户只要为系统提供一段IO的载体,IO有系统帮助用户来做。
换句话说,两者的区别点,在于数据在应用层和传输层之间的交换,是由应用程序来做还是由系统程序来做。
这里我们把Proactor模型的并发IO成为AIO,这也是AIO这个概念比较通用的解释。
支持AIO的系统可以是OS,比如Windows平台有IOCP。也可以是某个技术平台、虚拟机,比如Java AIO。甚至可以由硬件系统来做。
但我的问题只考虑软系统。我的问题是:无论是用户程序还是系统程序,它们总归是跑在硬件系统资源上的,都要消耗计算资源的。那从这个层面看,使用AIO与否似乎并不关乎我们要解决的高并发问题的最终成果。如果AIO的实际意义不体现在结果中,那它体现在哪里?是不是体现在开发过程中?
10 条回复    1970-01-01 08:00:00 +08:00
chenluois
    1
chenluois  
   2011-12-06 16:12:09 +08:00
汗~ 看到标题,我还以为是说双馨老师呢!
funcman
    2
funcman  
OP
   2011-12-06 16:29:41 +08:00
老师那是AOI
ssword
    3
ssword  
   2011-12-06 16:31:18 +08:00
并发模型有许多。在《Unix网络编程》里讲的很详细,可以看一下。

另外C10K问题也值得了解:
http://www.kegel.com/c10k.html
chenluois
    4
chenluois  
   2011-12-06 16:32:49 +08:00
@funcman 嗯。:)
funcman
    5
funcman  
OP
   2011-12-06 16:38:02 +08:00
@ssword 我的问题不是并发模型有哪些哦~
ssword
    6
ssword  
   2011-12-06 16:55:56 +08:00
@funcman 并发和负载都是很实际的问题。从问题到解决方案,都是从实际出发的。你问为什么要有异步IO,那可以实实在在的回答:解决或者缓解高并发的瓶颈问题,也就是C10K问题。

但是楼主对异步IO是怎样看的?如果对并发模型有部分常识,是不会将问题做二分法处理的。"异步IO"其实是个很含糊的称呼。起码非阻塞IO != 异步IO。

楼主说同样消耗资源,不错,但是消耗资源的多少有区别,这点细微的区别就可以成为瓶颈。比如,多线程+阻塞IO就比单线程+select/poll更浪费一分资源,select/poll又不如kqueue/epoll/iocp省资源。

好,既然epoll/kqueue是最终形态,大家还要其它模型做什么?非阻塞IO很难编程,很难调试。这就是得到性能的代价。至于actor模式等等,则是为了中和这部分复杂度而生的。
duoglas
    7
duoglas  
   2011-12-06 17:00:02 +08:00
@ssword 好厉害 仰慕一下
haohaolee
    8
haohaolee  
   2011-12-06 17:04:54 +08:00
只对IOCP有些认识,如果由OS来做IO,各种IO优化可以由OS来做,而且系统调用的次数会少些,而系统调用是很消耗指令周期的,但是缺乏灵活性。这里我是拿reactor和proactor比的。貌似通常情况下两者都被称为异步IO吧
moole
    9
moole  
   2011-12-06 18:33:26 +08:00
Reactor模式需要处理IO,Proactor把IO交给底层,所以后者比前者应该更利用上层通用性的封装。
funcman
    10
funcman  
OP
   2011-12-06 18:48:24 +08:00
@ssword
如果只是说阻塞/非阻塞、同步/异步,恐怕还是不能讲得太清。

阻塞发生在什么地方,一般来说发生在应用层向传输层的数据交换上。我们send/recv,实际上是与传输层打交道。比如recv,我们是把传输层的读缓冲区的数据搬到用户缓存区中,如果读缓冲区不可读(比如没数据),那阻塞模式下用户程序会停在的recv处,直到读缓冲区有了数据可以读了为止。这里的阻塞与否主要是socket意义上的。总的来说,阻塞是个容易理解的概念。

而异步这个概念,比较泛,不好谈。最广义的异步可以通过同步来模拟,如果如果,则如何,否则如何,这其中的“则如何”不同需要关心何时会“如果”。多路复用一种很经典的程序结构,就是把线路给Selector,Selector来告诉用户程序那些线路可以进行IO。select/poll/epoll/kqueue都可以作为Selector。其中select因为是轮询的,效率较差。而epoll是基于事件通知的,效率不错。使用epoll,无论是多个进程,还是多个线程,理论上效能都一回事,实际和linux的进程、线程调度有关系,和用户程序质量也有关系。使用epoll,监视IO的可读写性的工作交给了系统,而真正的数据搬运,用户程序自己来。正因为如此,我们不能说epoll是AIO,两者基本扯不上关系。当然,epoll可以帮助编写一套广泛意义上的AIO套件,比如epoll等到读写事件,就把活交给一个IO线程去办,办完再通过该套件自己的事件机制向用户发通知说我办完了。虽然这样多扰了几层,但一定程度还是符合AIO的定义的。

说这些,是想说我对IO模型的理解并没有多少偏差。我的观察是,大多数人用epoll就实现了高性能并发的需求,Linux虽然实现了一系列aio_*,但没多少人去用。而AIO好像并非是性能的终极方案。
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5564 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 23ms UTC 01:24 PVG 09:24 LAX 18:24 JFK 21:24
Do have faith in what you're doing.
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86