重新认识一下IO模型

    一直以来,对于BIO、NIO、AIO的认识,仅仅知道BIO是同步阻塞IO,NIO是同步非阻塞IO,AIO是异步阻塞IO,但是对于同步与异步、阻塞与非阻塞的概念却十分模糊,不能理解,现在整理一下相关只是:

    一般来说 I/O模型可以分为:同步阻塞,同步非阻塞,异步阻塞,异步非阻塞IO

    同步阻塞IO

    在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式!

    同步非阻塞IO

在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。

    异步阻塞IO

    此种方式下是指应用发起一个IO操作以后,不等待内核IO操作的完成,等内核完成IO操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问IO是否完成,那么为什么说是阻塞的呢?因为此时是通过select系统调用来完成的,而select函数本身的实现方式是阻塞的,而采用select函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!

    异步非阻塞IO

    在 此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行 处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。目前Java中还没有支持此种IO模型。  

    在高性能的I/O设计中,有两个比较著名的模式ReactorProactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作。


    我们分别以读操作和写操作为例来看看两种模式中的具体步骤:


Reactor模式读取操作:


    1. 应用程序注册读就需事件和相关联的事件处理器


    2. 事件分离器等待事件的发生


    3. 当发生读就需事件的时候,事件分离器调用第一步注册的事件处理器


    4. 事件处理器首先执行实际的读取操作,然后根据读取到的内容进行进一步的处理


    写入操作类似于读取操作,只不过第一步注册的是写就绪事件。


Proactor模式读取操作:



    1. 应用程序初始化一个异步读取操作,然后注册相应的事件处理器,此时事件处理器不关注读取就绪事件,而是关注读取完成事件,这是区别于Reactor的关键。


    2. 事件分离器等待读取操作完成事件


    3. 在事件分离器等待读取操作完成的时候,操作系统调用内核线程完成读取操作,并将读取的内容放入用户传递过来的缓存区中。这也是区别于Reactor的一点,Proactor中,应用程序需要传递缓存区。


    4. 事件分离器捕获到读取完成事件后,激活应用程序注册的事件处理器,事件处理器直接从缓存区读取数据,而不需要进行实际的读取操作。


    写入操作类似于读取操作,只不过感兴趣的事件是写入完成事件。

结论:Reactor和Proactor模式的主要区别就是真正的读取和写入操作是有谁来完成的,Reactor中需要应用程序自己读取或者写入数据,而Proactor模式中,应用程序不需要进行实际的读写过程,它只需要从缓存区读取或者写入即可,操作系统会读取缓存区或者写入缓存区到真正的IO设备.






标签: IO

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.jsunw.com/?post=8

相关推荐

你肿么看?

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。