I O復用 select和poll函式 一

2021-06-25 20:00:44 字數 3016 閱讀 8666

我們看到上面的tcp客戶同時處理兩個輸入:標準輸入和tcp套接字。我們遇到的問題就是在客戶阻塞於(標準輸入上的)fgets呼叫期間,伺服器程序會被殺死。伺服器tcp雖然正確地給客戶tcp傳送乙個fin,但是既然客戶程序阻塞於從標準輸入讀入的過程,它將看不到這個rof,知道從套接字讀時為止(可能已經過了很長時間)。這樣的程序需要一種預先告知核心的能力,使得核心一旦發現程序指定的乙個或多個i/o條件就緒(也就是說輸入已準備好被讀取,或者描述符已能承接更多的輸出),它就通知程序。這個能力成為i/o復用,是由select和poll這兩個函式支援的。

i/o復用典型使用在下列網路應用場合:

1)當客戶處理多個描述符(通常是互動式輸入和網路套接字)時,必須使用i/o復用

2)乙個客戶同時處理多個套接字是可能的,不過比較少見。在16.5節結合乙個web客戶的上下文給出這種場合使用select的例子

3)如果乙個tcp伺服器既要處理監聽套接字,又要處理已連線套接字,一般就要使用i/o復用

4)如果乙個伺服器既要處理tcp,又要處理udp,一般就要使用i/o復用。8.15節有這麼乙個例子

5)如果乙個伺服器要處理多個服務或者鍍鉻協議(在13.5節講述的inetd守護程序),就要用i/o復用

i/o復用並非只限於網路程式設計,許多重要的應用程式也需要使用這項技術

在unix下可用的5種i/o模型:

阻塞式i/o;

非阻塞式i/o;

i/o復用(select和poll);

訊號驅動式i/o;

非同步i/o

在上述所說的那樣,乙個輸入操作通常包括兩個不同的階段:

1)等待資料準備好;

2)從核心向程序複製資料

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

(1)阻塞時i/o模型:

最流行的i/o模型,本書到目前為止的所有例子都使用該模型。預設情形下,所有套接字都是阻塞的。

使用udp而不是tcp為例子的原因在於就udp而言,資料準備好讀取的概念比較簡單:要麼整個資料報已經收到,要麼還沒有。對於tcp而言,諸如套接字低水位標記等額外變數開始起作用,道指這個概念複雜。

我們把recvfrom函式視為系統呼叫,因為我們正在區分應用程序和核心。不管如何實現,一般都會從在應用程序空間中國執行切換到在核心空間中執行,一端時間之後再切換回來。 在上圖中,程序呼叫recvfrom,其系統呼叫直到資料報到達且被複製到應用程序的緩衝區中或者傳送錯誤才返回。最常見的錯誤是系統呼叫被訊號中斷,我們說程序在從呼叫recvfrom開始到它返回的整段時間內是被阻塞的。recvfrom成功返回後,應用程序開始處理資料報。

(2)非阻塞式i/o模型:

程序把乙個套接字設定成非阻塞是在通知核心:當所有請求的i/o操作非得把本程序投入睡眠才能完成時,不要把本程序投入睡眠,而是返回乙個錯誤。將在16章中詳細介紹非阻塞是i/o

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

當乙個應用程序像這樣對乙個非阻塞描述符迴圈呼叫recvfrom時,我們成為輪詢,應用程序持續輪詢核心,以檢視某個操作是否就緒。這麼做往往耗費大量cpu時間,不過這種模型偶爾也會遇到。

(3)i/o復用模型:

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

我們阻塞與select呼叫,等待資料報套接字變為可讀。當select返回套接字可讀這一條件時,我們呼叫recvfrom把所可讀資料報複製到應用程序緩衝區。比較上面兩圖,i/o復用並不顯得有什麼優勢,事實上由於使用select需要兩個而不是單個系統呼叫,其優勢在於可以等待多個描述符就緒

(4)訊號驅動式u/o模型:

可以用訊號,讓核心在描述符就緒時傳送sigio訊號通知我們。稱為訊號驅動式i/o

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

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

(5) 非同步i/o模型:

告知核心啟動某個操作,並讓核心在整個操作(包括將資料從核心複製到我們自己的緩衝區)完成後通知我們。這種模型與前一節介紹的訊號驅動模型的主要區別在於:訊號驅動i/o是由核心通知我們如何啟動乙個i/o操作,而非同步i/o模型是由核心通知我們i/o操作何時完成。

我們呼叫aio_read函式,給核心傳遞描述符、緩衝區指標。緩衝區大小和檔案偏移,並告訴核心當整個操作完成時如何通知我們。該系統呼叫立即返回,而且在等到i/o完成期間,我們的程序不被阻塞。

前四種模型的主要區別在於第一階段,因為它們的第二階段是一樣的:在資料從核心複製到呼叫者的緩衝區期間,程序阻塞與recvfrom呼叫。相反,非同步i/o模型在這兩個階段都要處理。

IO復用 select和poll 簡介

b contains b list 1 select 2 poll list b i o復用模型使用在下列網路應用場合 b list 1 當客戶處理多個fd時,必須使用i o復用。2 乙個客戶同事處理多個套接字是可能的。3 如果乙個tcp伺服器處理多個socket。4 如果乙個伺服器處理多個協議。l...

IO多路復用 select與poll

1.阻塞與非阻塞 阻塞方式block,程序執行到這一函式時必須等待事件發生,如果沒發生,就一直阻塞函式不能返回 非阻塞 non block 程序或執行緒執行不必等待事件發生一旦執行肯定返回以不停返回返回值來反應函式執 況 select就是這樣監視描述符的變化 2.select模型 兩結構體 stru...

第6章 I O復用 select和poll函式

如果乙個或多個 i o條件滿足,我們可以被通知到。場合 1.當客戶處理多個描述字時 2.乙個客戶同時處理多個套介面 3.乙個 tcp伺服器既要處理監聽套介面,又要處理已連線的套介面 4.乙個伺服器既要處理 tcp,又要處理 udp 5.乙個伺服器要處理多個服務或者多個協議 i o模型 l阻塞l 非阻...