同步I/O(阻塞I/O),异步I/O(非阻塞)

>同步I/O(阻塞I/O),异步I/O(非阻塞)·百家电脑学院: “同步I/O(阻塞I/O),异步I/O(非阻塞)

同步I/O(为什么叫做阻塞I/O),异步I/O(为什么叫做非阻塞)?写进去的和读出来的内容是一致叫做同步,而阻塞时是指当写/读完成时,要等待读/写在物理上完成后,才返回,这样才能保持读写或写读的一致性(因为这样才认为阻塞是同步吗?)

[ 本帖最后由 SybaseLU 于 2007-6-11 10:33 编辑 ]

rrrrrrrr8 2007-6-11 02:35
我只是很清楚什么叫阻塞和非阻塞.
I/O同步异步与阻塞非阻塞之间是什么关系,个人认为还不能直截划等号.请高手回答!

wflyfox 2007-6-11 03:03
阻塞模式下,调用accept,connect,read等函数会阻塞进程直到成功或者失败
非阻塞方式下,调用阻塞函数时(如read),如果没有数据可读,立即返回EAGAIN,不会阻塞在函数调用。

什么叫同步、异步呢?
请解答

SybaseLU 2007-6-11 03:56
1 众所周知,人们常常将read/write/…认为是阻塞I/O【不是还可以通过打开模式设定是NOBLOCK或是BLOCK吗?为什么直接说他们是阻塞I/O呢?】,而标准的ANSI 的fread/fwrite..都是非阻塞I/O【等待在物理上完成实际的I/O操作】
2 如果在一个进程中至少有2个以上的描述符,假设是fd1, fd2,如果需要将fd1的输入送到fd2上,将fd2的输出送到fd1的输入上,这时进程同时对2个输入和2个输出进行读写,采用非阻塞read/write, 他们如何被阻塞,而不得不采用select多路转换呢?

xhl 2007-6-11 04:19
原帖由 wflyfox 于 2007-6-11 11:03 发表
阻塞模式下,调用accept,connect,read等函数会阻塞进程直到成功或者失败
非阻塞方式下,调用阻塞函数时(如read),如果没有数据可读,立即返回EAGAIN,不会阻塞在函数调用。

什么叫同步、异步呢?
请解答 [/quote]

同步,异步的概念本来是通信领域的, 很难解释清楚, 但我肯定他跟阻塞非阻塞完全没有任何关系。

在这里的同步异步, 我个人的理解是函数调用的时候的同步异步。

其实同步方式很好理解, 例如你调用一个function, 当这个function执行完后, 这个方法实现的功能已经完成。这里往往会跟阻塞混淆,其实是因为你采用了同步方式执行代码, 才阻塞了你的thread或者process. 而不是因为阻塞,才叫同步。

异步方式就不提供这种保证, 当你用异步方式调用一个function的时候,这个方法会马上返回,事实上多数情况
下这种function call只是向某个任务执行体提交一个任务而已。 而你的主thread可以继续执行其他的事情, 不必等待(阻塞), 而当那个任务执行体执行完你提交的这个任务后,它会通过某种方法callback给你的thread, 告诉你,你的这个任务已经完成。

实际上,在目前的应用中, 很少有真正实现异步IO的(AIO), 听说(Windows 完成端口跟bsd kqueue实现了, 只是听说而已), 而通过select/poll等实现的不能算是AIO,只能说是个类似的或者是假冒的。。

因为用select/poll实现的情况下,他们多半都是把调用thread作为执行体thread的。

上面完全是个人理解,欢迎指正!

flw2 2007-6-11 04:26
我觉得阻塞和非阻塞主要是指读,而同步和异步是说写

非阻塞就是说: 如果没有数据我宁愿不要了,不要让我等,我还要干别的,我一会再来看有没有。
阻塞就是: 如果没有我要的数据,我的程序无法继续下去,所以没有就等等吧,没有关系,我没别的事情

同步就是写的时候真写了,而不是透明地放在某个地方。
异步就刚好相反了
不管是那个层次,比如fflush fsync等,都是说不要给我缓存,比如写一个优盘上的文件,优盘马上要被拔掉,那么写完之后很可能需要同步一下(虽然其实umount也肯定会同步)

zx_wing 2007-6-11 05:07
[quote]原帖由 xhl 于 2007-6-11 12:19 发表

同步,异步的概念本来是通信领域的, 很难解释清楚, 但我肯定他跟阻塞非阻塞完全没有任何关系。

在这里的同步异步, 我个人的理解是函数调用的时候的同步异步。

其实同步方式很好理解, 例如你调用一 … [/quote]
大概如此,不过只讲了概念,没有讲细节。我就简单补充一下linux中SIO(同步IO)和AIO(异步IO)机制
1.read/write:
对于read操作来说,它是同步的。也就是说只有当申请读的内容真正存放到buffer中后(user mode的buffer),read函数才返回。在此期间,它会因为等待IO完成而被阻塞。研究过源码的朋友应该知道,这个阻塞发生在两个地方:一是read操作刚刚发起,kernel会检查其它进程的need_sched标志,如果有其它进程需要调度,主动阻塞read操作,这个时候其实I/O操作还没有发起。二是I/O操作发起后,调用lock_page对已经加锁的页面申请锁,这时由于页面已经加锁,所以加锁操作被阻塞,从而read操作阻塞,直到I/O操作完成后页面被解锁,read操作继续执行。所以说read是同步的,其阻塞的原因如上。
对于write操作通常是异步的。因为linux中有page cache机制,所有的写操作实际上是把文件对应的page cache中的相应页设置为dirty,然后write操作返回。这个时候对文件的修改并没有真正写到磁盘上去。所以说write是异步的,这种方式下write不会被阻塞。如果设置了O_SYNC标志的文件,write操作再返回前会把修改的页flush到磁盘上去,发起真正的I/O请求,这种模式下会阻塞。
2.Direct I/O
linux支持Direct I/O, 以O_DIRCET标志打开的文件,在read和write的时候会绕开page cache,直接使用user mode的buffer做为I/O操作的buffer。这种情况下的read和write直接发起I/O操作,都是同步的,并会被阻塞。
3.AIO
目前大多数的linux用的AIO是基于2.4内核中的patch,使用librt库中的接口。这种方式实现很简单,就是一个父进程clone出子进程帮其做I/O,完成后通过signal或者callback通知父进程。用户看来是AIO,实质还是SIO。linux kernel中AIO的实现概念类似,只不过是以一组kernel thread去做的。这些kernel thread做I/O的时候使用的是和Direct I/O相同的方式。
4.mmap()
抛开它中讲vm_area和page cache映射在一起的机制不说。真正发起I/O时和read、write使用的是相同的机制,同步阻塞。

就简单的介绍一下,欢迎指正。

zx_wing 2007-6-11 05:10
[quote]原帖由 flw2 于 2007-6-11 12:26 发表
我觉得阻塞和非阻塞主要是指读,而同步和异步是说写

非阻塞就是说: 如果没有数据我宁愿不要了,不要让我等,我还要干别的,我一会再来看有没有。
阻塞就是: 如果没有我要的数据,我的程序无 …

>>我觉得阻塞和非阻塞主要是指读,而同步和异步是说写
同步、异步主要是指你读/写的内容和目标磁盘上对应的block时不时一样的
阻塞、非阻塞是指发起操作的函数是马上返回,还是被block直到操作完成”

此条目发表在Program, 转载分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>