網(wǎng)絡(luò)編程學(xué)習(xí)和實(shí)踐的過(guò)程中,同步(synchronous)/異步(asynchronous)與阻塞(blocking)/非阻塞(non-blocking)總是會(huì)迷惑很多人。依然記得我半年之前在記述IOCP時(shí),一句不經(jīng)意的“非阻塞I/O則是致力于提供高效的異步I/O”便引來(lái)一番口水論爭(zhēng)。
今天在查一些資料的時(shí)候,看到關(guān)于這幾個(gè)詞的論辯竟不是一般的多,細(xì)細(xì)想來(lái),這個(gè)問(wèn)題似乎也確實(shí)有解釋的必要,不在于爭(zhēng)論對(duì)錯(cuò),而在于辨明是非。
討論之前,先限定討論的范圍:此處之同步/異步僅限于I/O操作,與OS所討論的進(jìn)程/線程中的其他同步/異步沒(méi)有直接關(guān)系;討論的內(nèi)容是:兩對(duì)相似的術(shù)語(yǔ)之間的區(qū)別到底有多大。
Douglas C. Schmidt在《C++網(wǎng)絡(luò)編程》中這樣說(shuō)到:
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:例如,操作被異步調(diào)用時(shí),控制權(quán)交給客戶(hù)端,I/O操作請(qǐng)求則交由操作系統(tǒng)內(nèi)核處理,當(dāng)操作完成后,通過(guò)某種機(jī)制將結(jié)果通知客戶(hù)端。
非阻塞I/O:嘗試調(diào)用某操作,如果操作被阻塞,則調(diào)用返回-1并置錯(cuò)誤值為EWOULDBLOCK。
從這兩段“very different”的解釋來(lái)看,我的感覺(jué)是并沒(méi)有指出二者的區(qū)別,因?yàn)槲覀儫o(wú)法確定所謂AIO是如何處理的,如果AIO直接“調(diào)用返回-1并置錯(cuò)誤值為EWOULDBLOCK”,實(shí)現(xiàn)“控制權(quán)交給客戶(hù)端”,似乎并無(wú)任何不妥。況且,對(duì)于非阻塞I/O,我們也需要“當(dāng)操作完成后,通過(guò)某種機(jī)制將結(jié)果通知客戶(hù)端”這樣的處理。
而在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.
當(dāng)然,對(duì)于recv和send,我們一般會(huì)說(shuō)他們是阻塞起的,而不會(huì)說(shuō)他們是同步起的,但這顯然不是二者的區(qū)別,因?yàn)槲覀兌贾溃?strong>阻塞的原因正是等待同步結(jié)果的返回。
因此,二者的區(qū)別在于,阻塞/非阻塞是表現(xiàn),同步/異步是原因,我們說(shuō)某某操作是阻塞起的,或者某某線程是阻塞起的,是因?yàn)樵诘却僮鹘Y(jié)果的同步返回;我們說(shuō)某某操作是非阻塞的,是因?yàn)椴僮鹘Y(jié)果會(huì)通過(guò)異步方式返回。
討論到這兒,再咬文嚼字的爭(zhēng)辯下去似乎已經(jīng)沒(méi)有任何實(shí)際意義。
------------------------------------------------------------
PS:糾結(jié)一些必要的概念是為了加深理解,太過(guò)糾結(jié)了反倒會(huì)滯塞理解。我之前對(duì)于其概念也并非特別清楚,所以才會(huì)再續(xù)一篇特意言明,也算彌補(bǔ)一下自己的過(guò)失。