V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
funcman
V2EX  ›  问与答

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

  •  
  •   funcman · 2011-12-06 16:06:27 +08:00 · 5821 次点击
    这是一个创建于 4731 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我们在解决高性能并发问题时有两个并发模型: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   ·   实用小工具   ·   1124 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 18:46 · PVG 02:46 · LAX 10:46 · JFK 13:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.