一個IO操做涉及兩個系統對象:html
一個具體的Read操做包括兩個階段:編程
只有在同步的狀況下才會有「阻塞」和「非阻塞」之說,異步狀況,必須是非阻塞的!網絡
「同步 - 異步」指訪問數據的一種協做方式,同步須要主動讀寫數據,在讀寫數據的過程當中仍是會阻塞;異步只須要I/O操做完成的通知,並不主動讀寫數據,由內核完成數據的讀寫。「阻塞 - 非阻塞」指進程/線程要訪問的數據是否就緒,進程/線程是否須要等待。同步和異步着重點在於多個任務的執行過程當中,一個任務的執行是否會致使整個流程的暫時等待,阻塞和非阻塞着重點在於發出一個請求操做時,若是進行操做的條件不知足是否會返會一個標誌信息告知條件不知足。多線程
同步/異步僅關注消息通知的方式,並不關心消息如何處理,消息處理過程當中應用程序(線程)的狀態用阻塞/非阻塞來描述,是函數/方法的實現方式。併發
參考:socket阻塞與非阻塞、同步與異步概念詳解 - 1;socket阻塞與非阻塞、同步與異步概念詳解 - 2;異步
消息的通知機制,針對Client端(和Server端的交互),進程/線程觸發IO操做後:socket
其中,異步中處理的執行部經過三種途徑返回結果給調用者:函數
同步 Synchronousui
A Synchronous-I/O operation causes the requesting process to be blocked until that I/O operation completes.spa
串行,無條件等待,具體見下前4種I/O。
異步 Asynchronous
An Asynchronous-I/O operation does not cause the requesting process to be blocked.
併發,無需等待、無需輪詢,具體見下異步I/O。
應用程序在等待消息時的狀態,針對Server端,Server端是否阻塞與Client端無關,至於Client端在等待的前提下啥也不作仍是邊作其餘事邊等待,由Client端本身決定。關於阻塞/非阻塞,在網絡編程中一般應用在是否是須要等待數據就緒。
阻塞 Blocking
掛起等待,具體見下阻塞I/O。
非阻塞 Non-Blocking
輪詢檢查等待,具體見下非阻塞I/O。
阻塞I/O(Blocking I/O)
進程阻塞等待,進程掛起睡眠直到數據拷貝完成。
簡單易實現,不適於同時處理大量套接字、擴展性差。改進:
非阻塞I/O(Non-Blocking I/O)
進程非阻塞等待,數據準備階段進程不睡眠而是輪詢等待(致使CPU佔用率高)、數據拷貝階段進程阻塞。
便於處理多套接字的通訊,但實現複雜、需仔細檢查返回代碼並對收到的錯誤信息進行處理。
I/O多路複用(I/O Multiplexing) Reactor模式
對一個IO端口,兩次調用、兩次返回。
數據準備階段進程阻塞等待於select()/epoll()、數據拷貝階段進程阻塞,其中select()能夠同時阻塞多個I/O端口的操做,直到某個端口有數據可讀/寫時,才真正調用I/O操做函數。 實現同時對多個IO端口進行監聽,適於處理大量套接字的鏈接。
I/O多路複用經典模式(2種):
參考:Reactor和Proactor;
信號驅動I/O(Signal Driven I/O)
兩次調用,兩次返回。
數據準備階段進程繼續執行、數據拷貝階段進程阻塞。 須要創建信號處理程序。
異步I/O(Asynchronous I/O) Proactor模式
無阻塞,無需等待、無需輪詢、無需多線程。
異步過程調用,調用者不能馬上獲得結果,實際處理這個調用的部件在完成處理後,經過狀態、通知或回調來通知調用者。異步需操做系統的底層支持。
注:信號驅動模型由內核通知用戶能夠開始一個IO操做(數據在內核緩衝區中),異步IO由內核通知IO操做已經完成(數據已在用戶空間中)。
比較
同步IO - 異步IO:數據訪問時的消息通知機制,數據訪問/拷貝時(第二階段)進程是否等待,主動等待仍是被動通知等待消息的觸發! 同步IO和異步IO的關鍵區別反映在數據拷貝階段是由用戶線程完成仍是內核完成。
阻塞IO - 非阻塞IO:等待數據就緒時(第一階段)應用程序的調用是否當即返回!
推薦書籍:
參考: