UNIX系統的IO模型

2021-06-06 07:52:03 字數 3254 閱讀 8019

其實並非原創,只是摘錄了stevens的大作《unix網路程式設計》,寫下來,一、加深理解和記憶;二、書是借的,記錄一下備忘。感謝臻,借我此書一閱,受益匪淺。

阻塞式i/o

非阻塞式i/o

i/o復用;

訊號驅動式i/o

非同步i/o

乙個輸入操作通常包括兩個不同的階段: 1)

等待資料準備好; 2)

從核心向程序複製資料;

對於乙個套接字上的輸入操作,第一步通常涉及等待資料從網路中到達。當所等待分組到達時,它被複製到核心中的某個緩衝區。第二步就是把資料從核心緩衝區複製到應用程序緩衝區。

最流行的i/o模型是阻塞式i/o(blocking i/o)模型,預設情況下,所有套接字都是阻塞的。以資料報套接字作為例子,我們有如圖6-1所示的情形。

圖6-1  阻塞式i/o模型

在圖6-1中,程序呼叫recvfrom,其系統呼叫直到資料報到達且被複製到應用程序的緩衝區中或者發生錯誤才返回。我們說程序在從呼叫recvfrom開始到它返回的整段時間內是被阻塞的。recvfrom成功返回後,應用程序開始處理資料報。

程序把乙個套接字設定成非阻塞是在通知核心:當所請求的i/o操作非得把本程序投入睡眠才能完成時,不要把本程序投入睡眠,而是返回乙個錯誤。非阻塞式i/o(notblocking i/o)模型如圖6-2所示:

圖6-2  非阻塞式i/o模型

前三次呼叫recvfrom時沒有資料可返回,因此核心轉而立即返回乙個ewouldblock錯誤。第四次呼叫recvfrom時已有乙個資料報準備好,它被複製到應用程序緩衝區,於是recvfrom成功返回。我們接著處理資料。

當乙個應用程序像這樣對乙個非阻塞描述符迴圈呼叫recvfrom時,我們稱之為輪詢(polling)。應用程序只需輪詢核心,以檢視某個操作是否就緒。這麼做往往耗費大量cpu時間。

有了i/o復用(i/o multiplexing),我們就可以呼叫select或poll,阻塞在這兩個系統呼叫中的某乙個上,而不是阻塞在真正的i/o系統呼叫上。圖6-3概括展示了i/o復用模型。

圖6-3  i/o復用模型

我們阻塞於select呼叫,等待資料報套接字變為可讀。當select返回套接字可讀這一條件時,我們呼叫recvfrom把所讀資料報複製到應用程序緩衝區。

比較圖6-3和圖6-1,i/o復用並不顯得有什麼優勢,事實上由於使用select需要兩個而不是單個系統呼叫,i/o復用還稍有劣勢。使用select的優勢在於我們可以等待多個描述符就緒。

與i/o復用密切相關的另一種i/o模型是在多執行緒中使用阻塞式i/o(我們經常這麼幹)。這種模型與上述模型極為相似,但它並沒有使用select阻塞在多個檔案描述符上,而是使用多個執行緒(每個檔案描述符乙個執行緒),這樣每個執行緒都可以自由的呼叫recvfrom之類的阻塞式i/o系統呼叫了。

我們也可以用訊號,讓核心在描述符就緒時傳送sigio訊號通知我們。我們稱這種模型為訊號驅動式i/o(signal-driven i/o),圖6-4是它的概要展示。

圖6-4  訊號驅動式i/o模型

我們首先開啟套接字的訊號驅動式i/o功能,並通過sigaction系統呼叫安裝乙個訊號處理函式。改系統呼叫將立即返回,我們的程序繼續工作,也就是說他沒有被阻塞。當資料報準備好讀取時,核心就為該程序產生乙個sigio訊號。我們隨後就可以在訊號處理函式中呼叫recvfrom讀取資料報,並通知主迴圈資料已經準備好待處理,也可以立即通知主迴圈,讓它讀取資料報。

無論如何處理sigio訊號,這種模型的優勢在於等待資料報到達期間程序不被阻塞。主迴圈可以繼續執行,只要等到來自訊號處理函式的通知:既可以是資料已準備好被處理,也可以是資料報已準備好被讀取。

非同步i/o(asynchronous i/o)由posix規範定義。演變成當前posix規範的各種早起標準所定義的實時函式中存在的差異已經取得一致。一般地說,這些函式的工作機制是:告知核心啟動某個操作,並讓核心在整個操作(包括將資料從核心複製到我們自己的緩衝區)完成後通知我們。這種模型與前一節介紹的訊號驅動模型的主要區別在於:訊號驅動式i/o是由核心通知我們何時可以啟動乙個i/o操作,而非同步i/o模型是由核心通知我們i/o操作何時完成。圖6-5給出了乙個例子。

圖6-5  非同步i/o模型

我們呼叫aio_read函式(posix非同步i/o函式以aio_或lio_開頭),給核心傳遞描述符、緩衝區指標、緩衝區大小(與read相同的三個引數)和檔案偏移(與lseek類似),並告訴核心當整個操作完成時如何通知我們。該系統呼叫立即返回,並且在等待i/o完成期間,我們的程序不被阻塞。本例子中我們假設要求核心在操作完成時產生某個訊號。改訊號直到資料已複製到應用程序緩衝區才產生,這一點不同於訊號驅動i/o模型。

圖6-6對比了上述5中不同的i/o模型。可以看出,前4中模型的主要區別在於第一階段,因為他們的第二階段是一樣的:在資料從核心複製到呼叫者的緩衝區期間,程序阻塞於recvfrom呼叫。相反,非同步i/o模型在這兩個階段都要處理,從而不同於其他4中模型。

圖6-6  5種i/o模型的比較

posix把這兩個術語定於如下:

同步i/o操作(sysnchronous i/o opetation)導致請求程序阻塞,直到i/o操作完成;

非同步i/o操作(asynchronous i/o opetation)不導致請求程序阻塞。

根據上述定義,我們的前4種模型----阻塞式i/o模型、非阻塞式i/o模型、i/o復用模型和訊號驅動i/o模型都是同步i/o模型,因為其中真正的i/o操作(recvfrom)將阻塞程序。只有非同步i/o模型與posix定義的非同步i/o相匹配。

Unix系統IO模型簡介

阻塞式io 阻塞式io,即呼叫io函式之後阻塞,知道io操作完成後返回,繼續進行接下來的操作。非阻塞式io 程序把乙個套接字設定成非阻塞是在通知核心 當所請求的io操作不能立即完成而需要睡眠等待時,不要把本程序進入睡眠,而是返回乙個錯誤。io多路復用 io多路復用的方法有select poll ep...

IO模型之一 Unix的五種I O模型

1 阻塞i o blocking io 應用程式呼叫乙個io函式,導致應用程式阻塞,如果資料已經準備好,從核心拷貝到使用者空間,否則一直等待下去。乙個典型的讀操作流程大致如下圖,當使用者程序呼叫recvfrom這個系統呼叫時,kernel就開始了io的第乙個階段 準備資料,就是資料被拷貝到核心緩衝區...

二 UNIX網路I O模型

二 unix網路i o模型 1 阻塞i o模型 單操作而言 等待資料階段和拷貝資料階段都是阻塞的。2 非阻塞i o模型 單操作而言 等待資料階段是非阻塞的 不讓執行緒休眠 而拷貝資料仍然是阻塞的。可以不斷訪問其狀態 可讀可寫可連線 對成功與失敗馬上作出應對操作。3 i o復用模型 多操作而言 等待資...