linux 的 5 種 IO 模型

一、這裏 IO 是什麼

 操作系統爲了保護自己,設計了用戶態、內核態兩個狀態。應用程序一般工作在用戶態,當調用一些底層操作的時候(比如 IO 操作),就需要切換到內核態纔可以進行

服務器從網絡接收的大致流程如下:

1、數據通過計算機網絡來到了網卡

2、把網卡的數據讀取到 socket 緩衝區

3、把 socket 緩衝區讀取到用戶緩衝區,之後應用程序就可以使用

核心就是兩次讀取操作,五大 IO 模型的不同之處也就在於這兩個讀取操作怎麼交互

二、同步 / 異步和阻塞 / 非阻塞

三、五種 io 模型

  1. 阻塞 io

應用調用 recvfrom 讀取數據時,其系統調用直到數據包到達且被複制到應用緩衝區中或者發送錯誤時才返回,在此期間一直會等待,進程從調用到返回這段時間內都是被阻塞的稱爲阻塞 IO。在內核將數據準備好之前, 系統調用會一直等待. 所有的套接字, 默認都是阻塞方式

  1. 非阻塞 io

當應用發起讀取數據申請時,如果內核數據沒有準備好會即刻告訴應用 B,不會讓 B 在這裏等待, 如果內核還未將數據準備好, 系統調用仍然會直接返回, 並且返回 EWOULDBLOCK 錯誤碼。非阻塞 IO 往往需要程序員循環的方式反覆嘗試讀寫文件描述符

3.io 多路複用

由一個線程監控多個網絡請求(fd 文件描述符,linux 系統把所有網絡請求以一個 fd 來標識), 來完成數據狀態詢問的操作,當有數據準備就緒之後再分配對應的線程去讀取數據

下面給出一個應用系統和內核之間的流程圖

  1. 信號驅動

信號驅動 IO 是在調用 sigaction 時候建立一個 SIGIO 的信號聯繫,當內核準備好數據之後再通過 SIGIO 信號通知線程, 此 fd 準備就緒,當線程收到可讀信號後,此時再向內核發起 recvfrom 讀取數據的請求,因爲信號驅動 IO 的模型下, 應用線程在發出信號監控後即可返回,不會阻塞,所以一個應用線程也可以同時監控多個 fd

下面給出一個應用系統和內核之間的流程圖

  1. 異步 IO

應用只需要向內核發送一個讀取請求, 告訴內核它要讀取數據後即刻返回;內核收到請求後會建立一個信號聯繫,當數據準備就緒,內核會主動把數據從內核複製到用戶空間,等所有操作都完成之後,內核會發起一個通知告訴應用

四、五種 io 對比

可以看到,根據定義,前 4 種模型,在數據的讀取階段,全部都是阻塞的,因此是同步 IO。而異步 IO 模型在整個 IO 過程中都不阻塞,因此是異步 IO

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/-_xQVtG7dPJCUCCMijp_HA