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

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

另外C10K问题也值得了解:
http://www.kegel.com/c10k.html
chenluois
2011-12-06 16:32:49 +08:00
@funcman 嗯。:)
funcman
2011-12-06 16:38:02 +08:00
@ssword 我的问题不是并发模型有哪些哦~
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
2011-12-06 17:00:02 +08:00
@ssword 好厉害 仰慕一下
haohaolee
2011-12-06 17:04:54 +08:00
只对IOCP有些认识,如果由OS来做IO,各种IO优化可以由OS来做,而且系统调用的次数会少些,而系统调用是很消耗指令周期的,但是缺乏灵活性。这里我是拿reactor和proactor比的。貌似通常情况下两者都被称为异步IO吧
moole
2011-12-06 18:33:26 +08:00
Reactor模式需要处理IO,Proactor把IO交给底层,所以后者比前者应该更利用上层通用性的封装。
funcman
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好像并非是性能的终极方案。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/22942

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX