IO多路複用

什麼是IO多路複用?就是異步阻塞IO。目的在於提升系統效率。

服務器端編程經常需要構造高性能的IO模型,常見的IO模型有四種:

(1)同步阻塞IO(Blocking IO):即傳統的IO模型。

(2)同步非阻塞IO(Non-blocking IO):默認創建的socket都是阻塞的,非阻塞IO要求socket被設置爲NONBLOCK。

(3)IO多路複用(IO Multiplexing):即經典的Reactor設計模式,有時也稱爲異步阻塞IO,Java中的Selector和Linux中的epoll都是這種模型。

(4)異步IO(Asynchronous IO):即經典的Proactor設計模式,也稱爲異步非阻塞IO。

一、同步和異步

同步和異步的概念描述的是用戶線程與內核的交互方式:

同步是指用戶線程發起IO請求後需要等待或者輪詢內核IO操作完成後才能繼續執行;

異步是指用戶線程發起IO請求後仍繼續執行,當內核IO操作完成後會通知用戶線程,或者調用用戶線程註冊的回調函數。

二、阻塞和非阻塞

阻塞和非阻塞的概念描述的是用戶線程調用內核IO操作的方式:

阻塞是指IO操作需要徹底完成後才返回到用戶空間;

而非阻塞是指IO操作被調用後立即返回給用戶一個狀態值,無需等到IO操作徹底完成。

看圖比較容易明白。

三、同步阻塞IO

用戶需要等待read將socket中的數據讀取到buffer後,才繼續處理接收的數據。整個IO請求的過程中,用戶線程是被阻塞的,這導致用戶在發起IO請求時,不能做任何事情,對CPU的資源利用率不夠。
在這裏插入圖片描述

四、同步非阻塞IO

用戶線程發起IO請求後,立即返回;但需要不斷地調用read,嘗試讀取socket中的數據,直到讀取成功後,才繼續處理接收的數據。

雖然用戶線程每次發起IO請求後可以立即返回,但是爲了等到數據,仍需要不斷地輪詢、重複請求,消耗了大量的CPU的資源。一般很少直接使用這種模型,而是在其他IO模型中使用非阻塞IO這一特性。
在這裏插入圖片描述

五、異步阻塞IO(IO多路複用)

異步阻塞模型使用內核提供的select函數(多路分離函數),避免同步非阻塞模型中輪詢等待的問題。
在這裏插入圖片描述
表面上看,異步阻塞模型和同步阻塞模型沒有太大的區別,甚至還多了添加監視socket,以及調用select函數的額外操作,效率更差。但是,它最大的優勢是可以在一個線程內同時處理多個IO請求:用戶可以註冊多個socket,然後不斷地調用select讀取被激活的socket,即可達到在同一個線程內同時處理多個IO請求的目的,所以又叫IO多路複用模型

雖然上述方式允許單線程內處理多個IO請求,但是每個IO請求的過程還是阻塞的(在select函數上阻塞),平均時間甚至比同步阻塞IO模型還要長。如果用戶線程只註冊自己感興趣的socket或者IO請求,然後去做自己的事情,等到數據到來時再進行處理,則可以提高CPU的利用率。以下是改良版:
在這裏插入圖片描述

六、異步非阻塞IO(異步IO)

「真正」的異步IO需要操作系統更強的支持。在IO多路複用模型中,用戶線程收到通知後,自行讀取數據、處理數據。而在異步IO模型中,則由內核讀取數據,並放在緩衝區,用戶線程收到通知後,直接使用即可。
在這裏插入圖片描述

七、異步阻塞IO爲什麼叫IO多路複用

原因上面已經說了,IO多路複用其實就是異步阻塞IO,就是一個線程,可以同時處理多個IO請求(反過來不成立,一個IO請求只能對應一個線程)。

在這裏插入圖片描述
其實「I/O多路複用」這個說法之所以難以理解,可能是翻譯比較坑爹。所謂的I/O多路複用在英文中其實叫 I/O multiplexing。這裏面的 multiplexing 指的是通過跟蹤每一個Socket的狀態來同時管理多個I/O流。其目的,在於儘量多的提高服務器的吞吐能力。

在這裏插入圖片描述

八、同步異步、阻塞非阻塞爲什麼和多線程、IO聯繫在一起?

線程爲什麼會和IO扯在一起?

一個線程的執行,通常需要 3 個資源,即CPU,內存和I/O。CPU負責運行,內存負責存放即時數據,I/O負責和磁盤、數據庫、網絡等做數據交換。

I/O,即輸入/輸出。Java中,常見的I/O,有文件流,數據庫連接,網絡連接等。

I/O的特點是每個連接單位時間內只能爲一個線程服務,它不像CPU,即使是單核CPU,也可以通過時間切片的方式,執行多線程,多核CPU就更不用說了。IO只能爲單一線程服務。還有一個特點是,當一個線程在使用I/O時,一般耗時相對較長,且在這個時間段內,線程不進行計算或讀寫內存,換言之,線程在使用I/O時,一般不會使用CPU或內存。這個特點很重要,這其實是多線程的重要意義之一。在一個線程使用I/O時,將CPU使用權轉移給其它線程,可以更加充分的利用系統資源。

參考文章:
IO多路複用機制詳解

多線程與CPU、內存和I/O

IO 多路複用是什麼意思?