同步/异步,阻塞/非阻塞IO

看来网上一篇说同步/异步io,阻塞/非阻塞io概念区别的文章,感觉写的不错,使用去银行办理事务的比喻很生动贴切(原文在这里http://www.cppblog.com/converse/archive/2009/05/13/82879.html),然而我对此两组概念的理解与作者还是有所出入。作者所言,同步/异步是消息通知机制的不同,阻塞/非阻塞时程序等待消息时的状态不同。比如如果一个人去排队等待办理业务就是同步,而拿着序号等待叫号办理就是异步。如果排队时或等待叫号时还做其他事情就是非阻塞,如果不做其他事情而专一等待就是阻塞。如此说来的话,是否阻塞就是应用程序可以自由选择的了,这个显然是一个悖论,因为如果是这样的话,就不需要在打开文件或在socket上面设置Nonblock标志了,反正应用程序阻塞还是非阻塞都是可以自己选择的(调了select且设置超时为INFINITE等可读写事件就是阻塞,不调select自己轮询重试就是非阻塞)。按作者的理解的话,阻塞/非阻塞IO就是描述应用程序的等待策略而与IO无关了,我觉得这是不对的。

 

下面说说我的理解,仍然以去银行办理业务为喻,其实原文作者所说的同步/异步的区别,在我看来其实是阻塞/非阻塞的区别。你去银行办理业务,如果你选择排队方式就是阻塞的,此时你只有等待你自己的业务办完了,你才可以离开银行去做其他事,(对应于程序来说,就是打开文件或在socket上不设置nonblock标志,这时调用read/write函数,只有read/write完成后出错之后才返回);如果你选择等待叫号方式那么就是非阻塞的,你先拿一个号,如果刚好前面没人,下个号就是你,那么你可以马上把业务办完离开银行,如果前面有其他的人在办理,那么你可以选择在银行里等,也可以先去干别的,然后再来问问银行是不是轮到你了,如果轮到了你就办完走人,如果还没轮到你还可以去干别的事待会儿回来再问或者坐在银行里等(以程序来说就是,打开文件或在socket上设置了nonblock标志,这时调用read/write函数会马上返回,如果数据成功读出或写入,返回ok,如果当前没有数据可读,或缓冲区满暂时无法写入数据,就返回wouldBlock错误,告诉你待会儿再试,这时,你可以调用select等事件,或者先去做别的,下次再重试)。


那么什么同步/异步的区别又在哪里呢?还是延续前面的银行例子,如果你有空,愿意自己去银行办理,这时就是同步;如果你没时间,你托别人代你去办理,办完了告诉你一下就可以了,你自己去忙你自己的事,这时就是异步了。对应在程序里面,你的应用程序就代表你自己,同步时就是你的应用程序自己得去管排队还是拿号,并且自己去调用read/write函数去办理。而异步时,你调用的read/write函数就不是办理业务了,而是把这件事托付给操作系统内核去办理,内核自己去决定是排队还是拿号。内核办完了会告诉事情办得如何,是办成了还是没办成。

你可能感兴趣的:(同步/异步,阻塞/非阻塞IO)