UNIX五種I/O模型

UNIX的五種I/O模型:阻塞式I/O模型,非阻塞式I/O模型,I/O複用模型,信號驅動式I/O模型,異步I/O模型。這些概念看似容易混淆,從UNIX底層的I/O操作的角度來分析,其實不難理解。

一個輸入操作通常包括以下兩個階段:

  1. 等待數據準備好;包括等待數據從網絡中到達,數據到達後存入內核的緩衝區中。
  2. 從內核向進程複製數據。把數據從內核緩衝區複製到進程緩衝區。

下面要講的五種I/O模型實際上就是在這兩個階段中的阻塞策略不同。接下來以UDP的recvfrom爲例,進行說明。

阻塞式I/O模型

blocking IO,最直觀的I/O模型。應用進程調用recvfrom方法時,會進行阻塞,直到兩個階段都結束,數據複製到進程緩衝區時,方法才返回。成功返回後,應用程序再進行後續工作。流程如下圖所示:

image

非阻塞式I/O模型

此種模型下,recvfrom方法可立即返回。若內核數據沒有準備好,則返回一個錯誤;若數據準備好,進行第二階段複製操作,再返回成功指示。流程如下圖所示:

image

該種模型較爲少見,因爲往往需要應用程序持續輪詢內核,看看操作有沒有準備就緒。這樣會耗費大量CPU時間。

I/O複用模型

I/O複用是生產中最常見的網絡模型。調用select或者poll方法去查看內核中數據是否準備好,準備完畢即返回,否則保持阻塞。但是請注意,select調用和recvfrom調用往往不在一個線程中,所以此處的阻塞不會影響真正的IO操作。當套接字可讀,select返回,回調執行recvfrom,完成輸入操作。如下圖所示:

image

如果只是線性地看兩個階段是否有阻塞,IO複用似乎沒什麼優勢。但實際上,使用select的優勢在於“多路複用”,即一個selector等待多個文件描述符。

信號驅動式I/O模型

信號驅動式I/O模型,先通過sigaction調用安裝一個信號處理函數,並立即返回。當套接字可讀時,內核發送SIGIO信號通知應用程序,執行recvfrom方法執行IO輸入。如下圖所示:

image

這種模型,在接收到SIGIO信號之前,進程不會被阻塞。

異步I/O模型

前面四種IO模型,實際上在第二階段(從內核緩衝區讀取數據到用戶緩衝區)都是阻塞的。而異步I/O模型在兩個階段都是非阻塞的。即先告知內核啓動IO操作,立即返回,在兩個階段(準備數據和讀取數據)全部完成時,內核發送信號通知用戶進程。如下圖所示:
image

各種I/O模型的比較

首先明確兩個概念:同步I/O異步I/O,POSIX對其定義如下:

  • 同步I/O(synchronous I/O operation):導致請求進程阻塞,直到IO操作完成;
  • 異步I/O(asynchronous I/O operation):不導致請求進程阻塞。

五種模型的對比如下

image
五種I/O模型中,除了異步I/O,其餘四種或多或少都有阻塞的過程。因此,按照POSIX的標準,阻塞式I/O模型、非阻塞式I/O模型、I/O複用模型、信號驅動式I/O模型,都稱之爲同步I/O。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章