阻塞( blocking )、非阻塞( non-blocking ):能夠簡單理解爲須要作一件事能不能當即獲得返回應答,若是不能當即得到返回,須要等待,node
那就阻塞了(進程或線程就阻塞在那了,不能作其它事情),不然就能夠理解爲非阻塞(在等待的過程當中能夠作其它事情)。linux
同步( synchronous )、異步( asynchronous ): 你老是作完一件再去作另外一件,不論是否須要時間等待,這就是同步(就是在發出一個功能編程
調用時,在沒有獲得結果以前,該調用就不返回,即此時不能作下一件事情);異步則反之,你能夠同時作幾件事,並不是必定須要一件事作windows
完再作另外一件事(當一個異步過程調用發出後,調用者不能馬上獲得結果,此時能夠接着作其它事情)。同步簡單理解成一問一答同步進行,網絡
異步能夠簡單理解爲沒必要等一個問題有了答案再去問另外一個問題,儘管問,有答了再通知你。異步
阻塞和同步:socket
有人會把阻塞調用和同步調用等同起來,實際上他是不一樣的。 對於同步調用來講,不少時候當前線程仍是激活的,只是從邏輯上當前函數async
沒有返回而已 。 例如,咱們在socket中調用recv函數,若是緩衝區中沒有數據,這個函數就會一直等待,直到有數據才返回。而此時,當函數
前線程還會繼續處理各類各樣的消息。ui
針對網絡IO的操做,能夠分紅 兩個階段 ,準備階段和操做階段。
1,準備階段是判斷是否可以操做(即等待數據是否可用),在內核進程完成的;
2,操做階段則執行實際的IO調用,數據從內核緩衝區拷貝到用戶進程緩衝區。
好比對於一個read操做發生時,它會經歷下面兩個階段:
A, 等待數據準備,數據是否拷貝到內核緩衝區;
B, 將數據從內核拷貝到用戶進程空間
上面 兩點比較重要 ,注意理解。
《Unix網絡編程卷1:套接字聯網API》(即UNP)中第六章對unix 系統將IO模型分爲五類:阻塞IO,非阻塞IO,IO複用,信號驅動,異步IO。
一、阻塞IO:在準備階段即同步阻塞,應用進程調用I/O操做時阻塞,只有等待要操做的數據準備好,並複製到應用進程的緩衝區中才返回;
二、非阻塞IO:當應用進程要調用的I/O操做(第二階段)會致使該進程進入阻塞狀態時,該I/O調用返回一個錯誤,通常狀況下,應用進程須要利用輪詢的方式
來檢測某個操做是否就緒。數據就緒後,實際的I/O操做會等待數據複製到應用進程的緩衝區中之後才返回;
三、IO複用:多路IO共用一個同步阻塞接口,任意IO可操做均可激活IO操做,這是對阻塞IO的改進(主要是select和poll、epoll,關鍵是能實現同時對
多個IO端口進行監聽)。此時阻塞發生在select/poll的系統調用上,而不是阻塞在實際的I/O系統調用上。IO多路複用的高級之處在於:它能同時等
待多個文件描述符,而這些文件描述符(套接字描述符)其中的任意一個進入讀就緒狀態,select等函數就能夠返回。
四、信號驅動IO:註冊一個IO信號事件,在數據可操做時經過SIGIO信號通知線程,這應該算是一種異步機制;
以上四種模型在第一階段即判斷是否可操做階段各不相同,但一旦數據可操做,則切換到同步阻塞模式下執行IO操做,因此都算是同步IO。
5 、異步 IO: 應用進程通知內核開始一個異步I/O操做,並讓內核在整個操做(包含將數據從內核複製到應該進程的緩衝區)完成後通知應用進程。
根據上面所說的IO操做的兩個階段,能夠把上面的I/O模型進行以下歸類:
a,阻塞IO:在兩個階段上面都是阻塞的;
b,非阻塞IO:在第1階段,程序不斷的輪詢直到數據準備好,第2階段仍是阻塞的;
c,IO複用:在第1階段,當一個或者多個IO準備就緒時,通知程序,第2階段仍是阻塞的,在第1階段仍是輪詢實現的,只是全部的IO都集中在一個地方,這個地方進行輪詢;
d,信號IO:當數據準備完畢的時候,信號通知程序數據準備完畢,第2階段阻塞;
e,異步IO:1,2都不阻塞,異步IO模型 好比 windows之上的iocp,linux AIO,詳情點 這裏 ;
結果以下圖(圖來自UNP)。
阻塞式I/O模型、非阻塞式I/O模型、I/O複用模型,這三種模型的區別在於第一階段(阻塞式I/O 阻塞在I/O 操做上,非阻塞式I/O輪詢,
I/O複用阻塞在select/poll/epoll上),第二階段都是同樣的,即 這裏的阻塞不阻塞體如今第一階段 ,從這方面來講I/O複用類型也
能夠歸類到阻塞式I/O,它與阻塞式I/O的區別在於阻塞的系統調用不一樣。而異步I/O的兩個階段都不會阻塞進程。
其中POSIX將IO只分紅了同步IO、異步IO兩種模型。
同步 I/O 操做 :實際的I/O操做將致使請求進程阻塞, 直到 I/O 操做完成 。
異步 I/O 操做 :實際的I/O操做不致使請求進程阻塞。
由此,前面分類中:阻塞式I/O,非阻塞式I/O,I/O複用,信號驅動I/O模型都屬於同步I/O,由於 第二階段的數據複製都是阻塞的 。
而只有前面定義的異步I/O模型與這裏的異步I/O操做
同步或者異步I/O 主要是 指訪問數據的機制 (即 實際 I/O 操做的完成方式 ) ,同步 通常指主動請求並等待 I/O 操做完畢的方式 ,I/O操做
未完成前,會致使應用進程掛起;異步則指主動請求數據後即可以繼續處理其它任務,隨後等待I/O操做完畢的通知,這可使進程
在數據讀寫時也不阻塞。
阻塞或者非阻塞I/O 主要是指I/O操做第一階段的完成方式(進程訪問的數據若是還沒有就緒),即數據還未準備好的時候,應用進程
的表現,若是這裏進程掛起,則爲阻塞I/O,不然爲非阻塞I/O。
參考資料:
http://blog.csdn.net/hguisu/article/details/7453390