unix下5種基本的i/o模型:
1.阻塞i/o
2.非阻塞i/o
3.i/o復用(select和poll)
4.訊號驅動i/o(sigio)
5.非同步i/o(posix.1的aio_系列函式)
unix中乙個輸入操作一般有兩個不同的階段:
1.等待資料準備好。
2.從核心到程序拷貝資料。
對於乙個sockt上的輸入操作,第一步一般是等待資料到達網路,當分組到達時,它被拷貝到核心中的某個緩衝區,第二步是將資料從核心緩衝區拷貝到應用程式緩衝區。
下面分別介紹上面提到的5類i/o模型
本文中我們用udp來進行舉例,並且我們將函式recvfrom視為系統呼叫,這樣讓我們的注意力都集中在i/o模型上。
阻塞i/o模型
最流行的i/o模型是阻塞i/o模型,預設時,所有sockt都是阻塞的,這意味著當乙個sockt呼叫不能立即完成時,程序進入睡眠狀態,等待操作完成。如圖:
圖1 阻塞i/o模型
在圖1中,程序呼叫recvfrom,此呼叫直到資料報到達且拷貝到應用緩衝區或是出錯才返回。最常見的錯誤是系統呼叫被訊號中斷,我們所說程序阻塞的整段時間是指從呼叫recvfrom開始到它返回的這段時間,當程序返回成功指示時,應用程序開始處理資料報。
下面是乙個採用阻塞i/o模型編寫的簡單伺服器端**(本**來至於unix網路程式設計),這段**的功能是把客戶端發來的資料再回射到客戶端,本例子中程序阻塞於recvfrom.
#include "unp.h"
void dg_echo(int sockfd, sa *pcliaddr, socklen_t clilen);
intmain(int argc, char **argv)
void dg_echo(int sockfd, sa *pcliaddr, socklen_t clilen)}
非阻塞i/o模型
當我們把乙個sockt設定成非阻塞放式時,即通知核心:當請求的i/o操作非得讓程序睡眠才能完成時,不要讓程序睡眠,而應該返回乙個錯誤。如圖:
圖2 非阻塞i/o模型
如圖2所示,前3次呼叫recvfrom時仍無資料返回,因此核心立即返回乙個ewouldblock錯誤。第4次呼叫recvfrom時,資料報已經準備好了,被拷貝到應用緩衝區,recvfrom返回成功指示,接著就是我們處理資料報。
當乙個應用程序像這樣對乙個非阻塞sockt迴圈呼叫recvfrom時,我們稱此過程為輪詢(polling).應用程序連續不斷的查詢核心,看看某操作是否準備好,這對cpu是極大的浪費,但這種模型只是偶爾才遇到。
i/o復用模型
i/o復用能讓乙個或多個i/o條件滿足(例如,輸入已經準備好被讀,或者描述字可以承接更多的輸出)時,我們就被通知到。i/o復用由select和poll支援,較新的posix.1g也支援(pselect)。
i/o復用典型地用在下列網路應用場合:
1.當客戶處理多個描述字時,必須使用。
2.乙個客戶同時處理多個sockt.
3.如果乙個伺服器既要處理監聽sockt,又要處理連線sockt,一般也用到。
4.如果乙個伺服器既要處理tcp,又要處理udp,一般也用到。
5.如果乙個伺服器要處理多個服務或多個協議(例如inetd守護程序),一般也用到。
i/o復用並非限於網路程式設計,許多正是應用程式也需要使用這項技術。
有了i/o復用,我們就可以呼叫select或poll,在這兩個系統呼叫中的某乙個上阻塞,而不阻塞於真正的i/o系統呼叫。圖3是i/o復用模型的乙個小結。
圖3 i/o復用模型
我們阻塞於select呼叫,等待資料報socket可讀,當select返回socket可讀條件時,我們呼叫recvfrom將資料報拷貝到應用快取區中。
將圖3與圖1比較,似乎沒有顯示什麼優越性,實際上因使用了select,要求2此系統呼叫而不是一次,好像變的還有點差,但是select的好處在於我們可以等待多個描述字準備好。
訊號驅動 i/o模型
訊號驅動 i/o模型能在描述字準備好時用訊號sigio通知我們,下圖給出例子:
圖4 訊號驅動 i/o模型
首先我們允許sockt進行訊號驅動 i/o,並通過系統呼叫sigaction安裝乙個訊號處理程式。此系統呼叫立即返回,程序繼續工作,它是非阻塞的。當資料報準備好被讀時,就為該程序生成個sigio訊號。我們隨即可以在訊號處理程式中呼叫recvfrom來讀取資料報,並通知主迴圈資料已準備好被處理,也可以通知主迴圈,讓它來處理資料報。
無論我們如何處理sigio訊號,這種模型的好處是當等待資料報到達時,可以不阻塞。主迴圈可以繼續執行,只是等待訊號處理程式的通知:或者資料報已準備好被處理,或者資料報已準備好被讀取。
非同步i/o模型
非同步i/o模型是posix.1的1993版本中的新內容。我們讓核心啟動操作,並在整個操作完成後(包括將資料報從核心拷貝到我們自己的緩衝區)通知我們。這種模型與訊號驅動模型的主要區別在於:訊號驅動i/o是有核心通知我們何時可以啟動乙個i/o操作,而非同步i/o模型是由核心通知我們i/o操作何時完成。圖5給出了乙個例子。
圖5 非同步i/o模型
我們呼叫aio_red(posix非同步i/o函式以aio_或lio_開頭),給核心傳遞描述字、緩衝區指標、緩衝區大小(與red相同的3個引數)、檔案偏移(與lseek類似),並高書核心當整個操作完成時如何通知我們。此系統呼叫立即返回,我們的程序不阻塞於等待i/o操作的完成。在此例子中,我們假設要求核心在操作完成時產生乙個訊號,此訊號直到資料已拷貝到應用程式緩衝區才產生,這一點是於訊號驅動i/o模型不同的。
各種i/o模型的比較
圖6 各類i/o模型的比較
圖6給出了上述5中i/o模型的比較。它表明:前4種模型的區別都在第1階段,因為前4種模型的第2階段基本相同:在資料從核心拷貝到呼叫者的緩衝區時,程序阻塞於recvfrom呼叫。然而非同步i/o處理的兩個階段都不同於前4個模型。
同步i/o與非同步i/o
posix.1定義這兩個術語如下:
1.同步i/o操作引起請求程序阻塞,直到i/o操作完成。
2.非同步 i/o操作不引起請求程序阻塞。
根據上述定義,我們的前四個i/o模型都是同步i/o模型,因為真正的i/o操作(recvfrom)阻塞程序,只有非同步i/o模型與非同步i/o的定義相符合。
Unix下5種I O模型
unix下的5中i o模型 阻塞式i o 非阻塞式i o i o復用 select poll 訊號驅動式i o sigio 非同步i o posix的aio 系列函式 乙個輸入操作通常包括兩個不同階段 1 等待資料準備好 2 從核心向程序複製資料 對於套接字上的輸入操作,第一步等待資料從網路中到達,...
Unix下5種I O模型
unix下i o模型主要分為5種 1 阻塞式i o 2 非阻塞式i o 3 i o復用 select和poll 4 訊號驅動式i o 5 非同步i o 1 阻塞式i o模型 unix基本的套接字介面,例如 connect accept read write recv send recvfrom se...
Unix下5中I O模型
阻塞式i o 如建立socket連線,需要等待3次握手完成才可繼續向下執行程式,這期間就會造成cpu浪費,程式設計時用到的最多的,也是最初級的,非阻塞式i o 如建立socket連線,設定setblocking,則建立連線語句執行後立刻返回,無需等待,相比阻塞式i o缺點是,需要不停訪問資源是否準備...