码迷,mamicode.com
首页 > 其他好文 > 详细

关于IO的同步,异步,阻塞,非阻塞

时间:2015-08-08 16:42:57      阅读:96      评论:0      收藏:0      [点我收藏+]

标签:同步   异步   阻塞   非阻塞   

    关于网络IO的同步、异步、阻塞、非阻塞的文章网上有很多,搜索了对比了一下,观点也各不相同,即使是wiki也把异步和非阻塞区分得不是很清楚。下面我就结合《Unix网络编程 卷1》中的介绍,来说一说自己的理解。

    IO模型

    首先我们要先知道目前unix存在的五种IO模型,分别是:

  •     阻塞型IO(blocking I/O)
  •     非阻塞型IO(noblocking I/O)
  •     IO多路复用(I/O multiplexing)
  •     信号驱动(signal driven I/O)
  •     异步IO(asynchronous I/O)



    关于这五种模型这里就不详细介绍,大家有兴趣的话可以参考这篇博文,写的很详细:http://blog.csdn.net/sunyubo458/article/details/6096723


    IO的两个阶段

    1.等待数据准备好

    2.将数据从内核缓冲区复制到用户进程缓冲区


    同步,异步的区别

    那么究竟什么是同步和异步的区别呢?我的总结如下:

  •     同步IO,需要用户进程主动将存放在内核缓冲区中的数据拷贝到用户进程中。
  •     异步IO,内核会自动将数据从内核缓冲区拷贝到用户缓冲区,然后再通知用户。

    这样,同步和异步的概念就非常明显了。以上的五种IO模型,前面四种都是同步的,只有第五种IO模型才是异步的IO。


    阻塞和非阻塞

    那么阻塞和非阻塞呢?注意到以上五个模型。阻塞IO,非阻塞IO,只是上面的五个模型中的两个。阻塞,非阻塞,是针对单个进程而言的。

    我们先从阻塞和非阻塞socket来简单理解一下二者的区别:通常的,对一个文件描述符指定的文件或设备, 有两种工作方式: 阻塞与非阻塞方式。

    (1). 阻塞方式是指: 当试图对该文件描述符进行读写时,如果当时没有数据可读,或者暂时不可写,程序就进入等待状态,直到有东西可读或者可写为止。

    (2). 非阻塞方式是指: 如果没有数据可读,或者不可写,读写函数马上返回,而不会等待。

    (3). 举个例子来说,比如说小明去找一个女神聊天,女神却不在。 如果小明舍不得走,只能在女神大门口死等着,当然小明可以休息。当女神来了,她会把你唤醒(因为挡着她门了),这就是阻塞方式。如果小明发现女神不在,立即离开,以后每隔十分钟回来看一下(采用轮询方式),不在的话仍然立即离开,这就是非阻塞方式。

    (4). 阻塞方式和非阻塞方式唯一的区别: 是否立即返回。

   

    下面我们就来进行更深层次地理解

    当对多路复用IO进行调用时,比如使用poll。需注意的是,poll是系统调用,当调用poll的时候,其实已经是陷入了内核,是内核线程在跑了。因此对于调用poll的用户进程来讲,此时是阻塞的。

    因为poll的底层实现,是去扫描每个文件描述符(fd),而如果要对感兴趣的fd进行扫描,那么只能将每个描述符设置成非阻塞的形式(对于用户进程来讲,设置fd是阻塞还是非阻塞,可以使用系统调用fcntl),这样才有可能进行扫描。如果扫描当中,发现有可读(如果可读是用户感兴趣的)的fd,那么select就在用户进程层面就会返回,并且告知用户进程哪些fd是可读的。

    这时候,用户进程仍然需要使用read的系统调用,将fd的数据,从内核缓冲区拷贝到用户进程缓冲区(这也是poll为同步IO的原因)。

    那么此时的read是阻塞还是非阻塞的呢?这就要看fd的状态了,如果fd被设置成了非阻塞,那么此时read就是非阻塞的,否则就是阻塞的。不过程序已经执行到了这时候,不管fd是阻塞还是非阻塞,都没有任何区别,因为此前的poll,就是知道有数据准备好了才返回的,也就是说内核和缓冲区已经有了数据,此时进行read,是肯定能够将数据拷贝到用户进程的缓冲区的。

    但如果换种想法,如果poll是因为超时返回的,而我们又对一个fd(此时fd是被poll轮询过的)进行调用,那么此时是阻塞还是非阻塞,就非常有意义了。


    结论

    1.判断IO是同步还是异步,是看谁主动将数据拷贝到用户进程

    2.select或者poll,epoll,是同步调用

版权声明:本文为博主原创文章,未经博主允许不得转载。

关于IO的同步,异步,阻塞,非阻塞

标签:同步   异步   阻塞   非阻塞   

原文地址:http://blog.csdn.net/baidu_28312631/article/details/47357881

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!