我們所關心的檔案描述符
對每個描述符,我們所關心的狀態。(我們是要從乙個檔案描述符中讀或者寫,還是關注乙個描述符中是否出現異常)
我們要等待多長時間。(我們可以等待無限長的時間,等待固定的一段時間,或者根本就不等待)
有了這些返回資訊,我們可以呼叫合適的i/o函式(通常是read或 write),並且這些函式不會再阻塞。
返回:做好準備的檔案描述符的個數,超時為0, 錯誤為 -1.
有三種情況:
中間的三個引數 readset, writeset, exceptset,指向檔案描述符集。這些引數指明了我們關心哪些描述符,和需要滿足什麼條件(可寫,可讀,異常)。乙個檔案描述集儲存在 fd_set型別中。fd_set型別變數每一位代表了乙個描述符。我們也可以認為它只是乙個由很多二進位制位構成的陣列。如下圖所示:
對於fd_set型別的變數我們所能做的就是宣告乙個變數,為變數賦乙個同種型別的變數的值,或者使用以下幾個巨集觀控制它:
fd_zero巨集將乙個fd_set型別變數的所有位都設為0,使用fd_set將變數的某個位置位賦值。清除某個位時可以使用fd_clr,我們可以用fd_isset來測試某個位是否被置位。
fd_set rset;
int fd;
fd_zero(&rset);
fd_set(fd, &rset);
fd_set(stdin,&rset);
select返回後,用fd_isset測試給定位是否置位:
if(fd_isset(fd, &rset))
函式返回:
(1)當監視的相應的檔案描述符集中滿足條件時,比如說讀檔案描述符集中有資料到來時,核心(i/o)根據狀態修改檔案描述符集,並返回乙個大於0的數。
(2)當沒有滿足條件的檔案描述符,且設定的timeval監控時間超時時,select函式會返回乙個為0的值。
(3)當select返回負值時,發生錯誤。
理解select模型:
理解select模型的關鍵在於理解fd_set,為說明方便,取fd_set長度為1位元組,fd_set中的每一bit可以對應乙個檔案描述符fd。則1位元組長的fd_set最大可以對應8個fd。
(1)執行fd_set set;fd_zero(&set);則set用位表示是0000,0000。
(2)若fd=5,執行fd_set(fd,&set);後set變為0001,0000(第5位置為1)
(3)若再加入fd=2,fd=1,則set變為0001,0011
(4)執行select(6,&set,0,0,0)阻塞等待
(5)若fd=1,fd=2上都發生可讀事件,則select返回,此時set變為0000,0011。注意:沒有事件發生的fd=5被清空。
基於上面的討論,可以輕鬆得出select模型的特點:
(1)可監控的檔案描述符個數取決與sizeof(fd_set)的值。我這邊伺服器上sizeof(fd_set)=512,每bit表示乙個檔案描述符,則我伺服器上支援的最大檔案描述符是512*8=4096。據說可調,另有說雖然可調,但調整上限受於編譯核心時的變數值。
(2)將fd加入select監控集的同時,還要再使用乙個資料結構array儲存放到select監控集中的fd,一是用於再select返回後,array作為源資料和fd_set進行fd_isset判斷。二是select返回後會把以前加入的但並無事件發生的fd清空,則每次開始 select前都要重新從array取得fd逐一加入(fd_zero最先),掃瞄array的同時取得fd最大值maxfd,用於select的第乙個引數。
(3)可見select模型必須在select前迴圈array(加fd,取maxfd),select返回後迴圈array(fd_isset判斷是否有時間發生)。
基本原理
linux select函式詳解
在linux中,我們可以使用select函式實現i o埠的復用,傳遞給 select函式的引數會告訴核心 我們所關心的檔案描述符 對每個描述符,我們所關心的狀態。我們是要想從乙個檔案描述符中讀或者寫,還是關注乙個描述符中是否出現異常 我們要等待多長時間。我們可以等待無限長的時間,等待固定的一段時間,...
linux select函式用法詳解
函式主要功能 呼叫select 函式,可以讓程序指示核心等待多個事件中的任意乙個發生,並使程序處於阻塞狀態,直到 select 引數指定的事情或者關心的事情發生時候,才喚醒程序,並且函式返回準備就緒的事件個數。函式原型 include int select int maxfdp1 fd set re...
原 linux select函式詳解
在linux中,我們可以使用select函式實現i o埠的復用,傳遞給 select函式的引數會告訴核心 我們所關心的檔案描述符 對每個描述符,我們所關心的狀態。我們是要想從乙個檔案描述符中讀或者寫,還是關注乙個描述符中是否出現異常 我們要等待多長時間。我們可以等待無限長的時間,等待固定的一段時間,...