当时我答得比较烂,大概就是举了些例子,比如线(进)程的同步,以及系统调用的阻塞非阻塞。它们之间真正的区别从来没有完全梳理清楚过。哪位网友能够给
一个比较清晰的解释?
阻塞和非阻塞很好区别,所谓阻塞就是系统调用在IO调用完成时才返回,被阻塞的进程处于睡眠状态。
非阻塞IO是指不管系统调用是否完成都立刻返回,不会导致进程挂起。服务器的设计中都使用非阻塞IO,用于响应高并发的连接请求。
这里还有个概念就是IO复用,其实是阻塞到select或poll等这样的系统调用,而不是真正的read或write。
同步和异步IO:下面是POSIX的定义
所谓同步IO就是请求进程阻塞到直到IO操作完成时。阻塞IO和非阻塞IO都是同步IO。
异步IO就是IO操作不会引起请求进程的阻塞。
下面的话引自UNPv1
A synchronous I/O operation causes the requesting process to be
blocked until that I/O operation completes.
An asynchronous I/O operation does not cause the requesting process to
be blocked.
在 2011年8月9日 下午3:08,麻油蒜泥 <gin.y...@gmail.com> 写道:
目前unix存在五种IO模型(这也和上一篇文章:Unix IO 模型 中提到的一致),分别是:
那么究竟什么是同步和异步的区别呢?请重点读一下原文6.2节中的信号驱动IO和异步IO中的比较。最后总结出来是:
这样,同步和异步的概念就非常明显了。以上的五种IO模型,前面四种都是同步的,只有第五种IO模型才是异步的IO。
那么阻塞和非阻塞呢?注意到以上五个模型。阻塞IO,非阻塞IO,只是上面的五个模型中的两个。阻塞,非阻塞,是针对单个进程而言的。
当对多路复用IO进行调用时,比如使用poll。需注意的是,poll是系统调用,当调用poll的时候,其实已经是陷入了内核,是内核线程在跑了。因此对于调用poll的用户进程来讲,此时是阻塞的。
因为poll的底层实现,是去扫描每个文件描述符(fd),而如果要对感兴趣的fd进行扫描,那么只能将每个描述符设置成非阻塞的形式(对于用户进程来讲,设置fd是阻塞还是非阻塞,可以使用系统调用fcntl),这样才有可能进行扫描。如果扫描当中,发现有可读(如果可读是用户感兴趣的)的fd,那么select就在用户进程层面就会返回,并且告知用户进程哪些fd是可读的。
这时候,用户进程仍然需要使用read的系统调用,将fd的数据,从内核缓冲区拷贝到用户进程缓冲区(这也是poll为同步IO的原因)。
那么此时的read是阻塞还是非阻塞呢?这就要看fd的状态了,如果fd被设置成了非阻塞,那么此时的read就是非阻塞的;如果fd被设置成了阻塞,那么此时的read就是阻塞的。
不过程序已经执行到了这时候,不管fd是阻塞还是非阻塞,都没有任何区别,因为之前的poll,就是知道有数据准备好了才返回的,也就是说内核缓冲区已经有了数据,此时进行read,是肯定能够将数据拷贝到用户进程缓冲区的。
但如果换种想法,如果poll是因为超时返回的,而我们又对一个fd(此fd是被poll轮询过的)进行read调用,那么此时是阻塞还是非阻塞,就非常有意义了,对吧!
阻塞与非阻塞,取决于该函数调用是否可能导致当前用户态线程sleep?
同步与异步,取决于该函数调用的结果(这里的“结果”不仅仅指返回值,还可能包含其它信息),是在函数返回的时机获取呢,还是通过另外一个上下文进行通知?
没事瞎琢磨,纯属个人意见,欢迎拍砖。
On 8/10/11, 李玉林 <yulin...@gmail.com> wrote:
> IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇) - 智障大师 的专栏 -
> CSDN博客<http://blog.csdn.net/historyasamirror/article/details/5778378>
>
> 在 2011年8月10日 上午9:58,jaywong <jaywon...@gmail.com>写道:
>
>> IO模型
>>
>> 目前unix存在五种IO模型(这也和上一篇文章:Unix IO 模型 <http://www.zavakid.com/70>
>> 中提到的一致),分别是:
>> 阻塞型 IO(blocking I/O)
>> 非阻塞性IO(nonblocking I/O)
>> IO多路复用(I/O multiplexing)
>> 信号驱动IO(signal driven I/O)
>> 异步IO(asynchronous I/O) IO的两个阶段
>> 等待数据准备好
>> 将数据从内核缓冲区复制到用户进程缓冲区同步,异步的区别
>>
>>
>> 那么究竟什么是同步和异步的区别呢?请重点读一下原文<http://u.115.com/file/bh06p2sr#UNIX_Network_Programming.chm>
>> 6.2节中的信号驱动IO和异步IO中的比较。最后总结出来是:
>> 同步IO,需要用户进程主动将存放在内核缓冲区中的数据拷贝到用户进程中。
>> 异步IO,内核会自动将数据从内核缓冲区拷贝到用户缓冲区,然后再通知用户。
>>
>> 这样,同步和异步的概念就非常明显了。以上的五种IO模型,前面四种都是同步的,只有第五种IO模型才是异步的IO。
>> 阻塞和非阻塞
>>
>> 那么阻塞和非阻塞呢?注意到以上五个模型。阻塞IO,非阻塞IO,只是上面的五个模型中的两个。阻塞,非阻塞,是针对单个进程而言的。
>>
>>
>>
>> 当对多路复用IO进行调用时,比如使用poll。需注意的是,poll是系统调用,当调用poll的时候,其实已经是陷入了内核,是内核线程在跑了。因此对于调用poll的用户进程来讲,此时是阻塞的。
>>
>>
>>
>> 因为poll的底层实现,是去扫描每个文件描述符(fd),而如果要对感兴趣的fd进行扫描,那么只能将每个描述符设置成非阻塞的形式(对于用户进程来讲,设置fd是阻塞还是非阻塞,可以使用系统调用fcntl),这样才有可能进行扫描。如果扫描当中,发现有可读(如果可读是用户感兴趣的)的fd,那么select就在用户进程层面就会返回,并且告知用户进程哪些fd是可读的。
>>
>> 这时候,用户进程仍然需要使用read的系统调用,将fd的数据,从内核缓冲区拷贝到用户进程缓冲区(这也是poll为同步IO的原因)。
>>
>>
>>
>> 那么此时的read是阻塞还是非阻塞呢?这就要看fd的状态了,如果fd被设置成了非阻塞,那么此时的read就是非阻塞的;如果fd被设置成了阻塞,那么此时的read就是阻塞的。
>>
>>
>>
>> 不过程序已经执行到了这时候,不管fd是阻塞还是非阻塞,都没有任何区别,因为之前的poll,就是知道有数据准备好了才返回的,也就是说内核缓冲区已经有了数据,此时进行read,是肯定能够将数据拷贝到用户进程缓冲区的。
>>
>>
>>
>> 但如果换种想法,如果poll是因为超时返回的,而我们又对一个fd(此fd是被poll轮询过的)进行read调用,那么此时是阻塞还是非阻塞,就非常有意义了,对吧!
>> 结论
>> 判断IO是同步还是异步,是看谁主动将*数据*拷贝到用户进程。
>> select或者poll,epoll,是同步调用,进行此调用的用户进程也处于阻塞状态。
>> javaScript或者nodejs中的读取网络(文件)数据,然后提供回调函数进行处理,是异步IO。
>>
>> from http://blogread.cn/it/article.php?id=4108&f=sinat
>>
>> --
>> jaywong
>> 已使用 Sparrow <http://www.sparrowmailapp.com/?sig> 发送
>> 已使用 Sparrow <http://www.sparrowmailapp.com/?sig> 发送
改正为:同步与异步,取决于该函数调用的功能完成后的结果(这里的“结果”不仅仅指返回值,还可能包含其它信息),是在函数返回的时机获取呢,还是通过另外一个上下文进行通知?
加上“完成”等关键字,方便熟悉windows完成端口模型的朋友理解。
另外比较狭义一点去理解“异步”(其实也是最常见的一种)的话,上文所述的“通过另外一个上下文进行通知”一定是发生了内核线程向用户线程的通信请求。
广义一点来看,投射消息到消息队列然后消息队列再派发消息到消息泵去处理这个典型模型也算得上“异步”。
感觉你没有对阻塞非阻塞进行解释啊,请问为什么nodejs宣称是非阻塞的呢?
On 8月12日, 上午11时51分, Tomas Huang (冠) <huangguan3112...@gmail.com>
wrote:
> 感觉你没有对阻塞非阻塞进行解释啊,请问为什么nodejs宣称是非阻塞的呢?
> 在 2011-8-10 上午9:58,"jaywong" <jaywong.sm...@gmail.com>写道:
>
>
>
>
>
>
>
>
>
> > IO模型
>
> > 目前unix存在五种IO模型(这也和上一篇文章:Unix IO 模型 中提到的一致),分别是:
>
> > 阻塞型 IO(blocking I/O)
> > 非阻塞性IO(nonblocking I/O)
> > IO多路复用(I/O multiplexing)
> > 信号驱动IO(signal driven I/O)
> > 异步IO(asynchronous I/O)
> > IO的两个阶段
> > 等待数据准备好
> > 将数据从内核缓冲区复制到用户进程缓冲区
> > 同步,异步的区别
>
> > 那么究竟什么是同步和异步的区别呢?请重点读一下原文6.2节中的信号驱动IO和异步IO中的比较。最后总结出来是:
>
> > 同步IO,需要用户进程主动将存放在内核缓冲区中的数据拷贝到用户进程中。
> > 异步IO,内核会自动将数据从内核缓冲区拷贝到用户缓冲区,然后再通知用户。
>
> > 这样,同步和异步的概念就非常明显了。以上的五种IO模型,前面四种都是同步的,只有第五种IO模型才是异步的IO。
>
> > 阻塞和非阻塞
>
> > 那么阻塞和非阻塞呢?注意到以上五个模型。阻塞IO,非阻塞IO,只是上面的五个模型中的两个。阻塞,非阻塞,是针对单个进程而言的。
>
> 当对多路复用IO进行调用时,比如使用poll。需注意的是,poll是系统调用,当调用poll的时候,其实已经是陷入了内核,是内核线程在跑了。因此对于调 用poll的用户进程来讲,此时是阻塞的。
>
> 因为poll的底层实现,是去扫描每个文件描述符(fd),而如果要对感兴趣的fd进行扫描,那么只能将每个描述符设置成非阻塞的形式(对于用户进程来讲,设置 fd是阻塞还是非阻塞,可以使用系统调用fcntl),这样才有可能进行扫描。如果扫描当中,发现有可读(如果可读是用户感兴趣的)的fd,那么select就 在用户进程层面就会返回,并且告知用户进程哪些fd是可读的。
>
> > 这时候,用户进程仍然需要使用read的系统调用,将fd的数据,从内核缓冲区拷贝到用户进程缓冲区(这也是poll为同步IO的原因)。
>
> 那么此时的read是阻塞还是非阻塞呢?这就要看fd的状态了,如果fd被设置成了非阻塞,那么此时的read就是非阻塞的;如果fd被设置成了阻塞,那么此时 的read就是阻塞的。
>
> 不过程序已经执行到了这时候,不管fd是阻塞还是非阻塞,都没有任何区别,因为之前的poll,就是知道有数据准备好了才返回的,也就是说内核缓冲区已经有了数 据,此时进行read,是肯定能够将数据拷贝到用户进程缓冲区的。
>
> 但如果换种想法,如果poll是因为超时返回的,而我们又对一个fd(此fd是被poll轮询过的)进行read调用,那么此时是阻塞还是非阻塞,就非常有意义 了,对吧!
>
>
>
>
>
>
>
>
>
> > 结论
> > 判断IO是同步还是异步,是看谁主动将数据拷贝到用户进程。
> > select或者poll,epoll,是同步调用,进行此调用的用户进程也处于阻塞状态。
> > javaScript或者nodejs中的读取网络(文件)数据,然后提供回调函数进行处理,是异步IO。
>
> > fromhttp://blogread.cn/it/article.php?id=4108&f=sinat
>
> > --
> > jaywong
> > 已使用 Sparrow 发送
> > 已使用 Sparrow 发送
>
> > 在 2011年8月9日星期二,下午4:45,linux JHON 写道:
>
> >> 同步在进程和线程之间存在,也同样存在于IO。但是根据这里的上下文,应该问的是IO的同步。线程或进程的同步和互斥是另外一个话题了。
>
> >> 阻塞和非阻塞很好区别,所谓阻塞就是系统调用在IO调用完成时才返回,被阻塞的进程处于睡眠状态。
> >> 非阻塞IO是指不管系统调用是否完成都立刻返回,不会导致进程挂起。服务器的设计中都使用非阻塞IO,用于响应高并发的连接请求。
> >> 这里还有个概念就是IO复用,其实是阻塞到select或poll等这样的系统调用,而不是真正的read或write。
>
> >> 同步和异步IO:下面是POSIX的定义
> >> 所谓同步IO就是请求进程阻塞到直到IO操作完成时。阻塞IO和非阻塞IO都是同步IO。
> >> 异步IO就是IO操作不会引起请求进程的阻塞。
>
> >> 下面的话引自UNPv1
> >> A synchronous I/O operation causes the requesting process to be
> >> blocked until that I/O operation completes.
> >> An asynchronous I/O operation does not cause the requesting process to
> >> be blocked.
>