Posted on 2008-09-11 01:11
Fox 阅读(4951)
评论(12) 编辑 收藏 引用 所属分类:
T技术碎语
网络编程学习和实践的过程中,同步(synchronous)/异步(asynchronous)与阻塞(blocking)/非阻塞(non-blocking)总是会迷惑很多人。依然记得我半年之前在记述IOCP时,一句不经意的“非阻塞I/O则是致力于提供高效的异步I/O”便引来一番口水论争。
今天在查一些资料的时候,看到关于这几个词的论辩竟不是一般的多,细细想来,这个问题似乎也确实有解释的必要,不在于争论对错,而在于辨明是非。
讨论之前,先限定讨论的范围:此处之同步/异步仅限于I/O操作,与OS所讨论的进程/线程中的其他同步/异步没有直接关系;讨论的内容是:两对相似的术语之间的区别到底有多大。
Douglas C. Schmidt在《C++网络编程》中这样说到:
They are very different, as follows:
AIO is "asynchronous I/O", i.e., the operation is invoked asynchronously and control returns to the client while the OS kernel processes the I/O request. When the operation completes there is some mechanism for the client to retrieve the results.
Non-blocking I/O tries an operation (such as a read() or write()) and if it the operation would block (e.g., due to flow control on a TCP connection or due to lack of data in a socket), the call returns -1 and sets errno to EWOULDBLOCK.
翻译如下:
异步I/O:例如,操作被异步调用时,控制权交给客户端,I/O操作请求则交由操作系统内核处理,当操作完成后,通过某种机制将结果通知客户端。
非阻塞I/O:尝试调用某操作,如果操作被阻塞,则调用返回-1并置错误值为EWOULDBLOCK。
从这两段“very different”的解释来看,我的感觉是并没有指出二者的区别,因为我们无法确定所谓AIO是如何处理的,如果AIO直接“调用返回-1并置错误值为EWOULDBLOCK”,实现“控制权交给客户端”,似乎并无任何不妥。况且,对于非阻塞I/O,我们也需要“当操作完成后,通过某种机制将结果通知客户端”这样的处理。
而在Wikipedia上则直接等同二者:Asynchronous I/O, or non-blocking I/O, is a form of input/output processing that permits other processing to continue before the transmission has finished.
当然,对于recv和send,我们一般会说他们是阻塞起的,而不会说他们是同步起的,但这显然不是二者的区别,因为我们都知道,阻塞的原因正是等待同步结果的返回。
因此,二者的区别在于,阻塞/非阻塞是表现,同步/异步是原因,我们说某某操作是阻塞起的,或者某某线程是阻塞起的,是因为在等待操作结果的同步返回;我们说某某操作是非阻塞的,是因为操作结果会通过异步方式返回。
讨论到这儿,再咬文嚼字的争辩下去似乎已经没有任何实际意义。
------------------------------------------------------------
PS:纠结一些必要的概念是为了加深理解,太过纠结了反倒会滞塞理解。我之前对于其概念也并非特别清楚,所以才会再续一篇特意言明,也算弥补一下自己的过失。