Linux下select 機制中fd set用法

2021-06-05 10:53:11 字數 2331 閱讀 6505

select()機制中提供一fd_set的資料結構,實際上是一long型別的陣列,每乙個陣列元素都能與一開啟的檔案控制代碼(不管是socket控制代碼,還是其他檔案或命名管道或裝置控制代碼)建立聯絡,建立聯絡的工作由程式設計師完成,當呼叫select()時,由核心根據io狀態修改fe_set的內容,由此來通知執行了select()的程序哪一socket或檔案可讀。

多埠復用函式select在呼叫前要首先設定監聽的埠數目,fd_zero是清空埠集,fd_set是設定埠集。

select()函式常常用在用乙個程序監聽多個伺服器端socket。

有時,select()也被當作延時函式使用。sleep()延時會釋放cpu,select()的話,可以在占用cpu的情況下延時。

select()函式主要是建立在fd_set型別的基礎上的。fd_set(它比較重要所以先介紹一下)是一組檔案描述字(fd)的集合,它用一位來表示乙個fd(下面會仔細介紹),對於fd_set型別通過下面四個巨集來操作:

fd_set  set;

fd_zero(&set);        /*將set清零使集合中不含任何fd*/

fd_set(fd, &set);      /*將fd加入set集合*/

fd_clr(fd, &set);      /*將fd從set集合中清除*/

fd_isset(fd, &set);   /*測試fd是否在set集合中*/

過去,乙個fd_set通常只能包含<32的fd(檔案描述字),因為fd_set其實只用了乙個32位向量來表示fd; 現在,unix系統通常會在標頭檔案中定義常量fd_setsize,它是資料型別fd_set的描述字數量,其值通常是1024,這樣就能表示<1024的fd。根據fd_set的位向量實現,我們可以重新理解操作fd_set的四個巨集:

fd_set  set;

fd_zero(&set);        /*將set的所有位置0,如set在記憶體中佔8位則將set置為00000000*/

fd_set(0, &set);       /*將set的第0位置1,如set原來是00000000,則現在變為100000000,這樣fd==1的檔案描述字就被加進set中了*/

fd_clr(4, &set);       /*將set的第4位置0,如set原來是10001000,則現在變為10000000,這樣fd==4的檔案描述字就被從set中清除了*/

fd_isset(5, &set);     /*測試set的第5位是否為1,如果原來set是10000100,則返回非零,表明fd==5的檔案描述符在set中,否則返回0*/

注意:fd的最大值必須

select函式的介面比較簡單:

int select(int nfds,  fd_set* readset,  fd_set* writeset,  fe_set* exceptset,  struct timeval* timeout);

功能:測試指定的fd可讀?可寫?有異常條件待處理?

引數:nfds: 需要檢查的檔案描述字個數(即檢查到fd_set的第幾位),數值應該比三組fd_set中所含的最大fd值更大,一般設為三組fd_set中所含的最大fd值加1(如在readset, writeset, exceptset中所含最大的fd為5,則nfds=6,因為fd是從0開始的 )。設這個值是為了提高效率,使函式不必檢查fd_set的所有1024位。

readset: 用來檢查可讀性的一組檔案描述字。

writeset: 用來檢查可寫性的一組檔案描述字。

exceptset: 用來檢查是否有異常條件出現的檔案描述字。(注:錯誤不包括在異常條件之內)

timeout: 有三種可能:

1.  timeout = null (阻塞:直到有乙個fd位被置為1函式才返回)

3.  timeout所指向的結構,時間設為0(非阻塞:函式檢查完每乙個fd後立即返回)

返回值:返回對應位仍然為1的fd的總數。

remark:

三組fd_set均將某些fd位置0,只有那些可讀,可寫以及有異常條件待處理的fd位仍然為1。

使用select函式的過程一般是:

先呼叫巨集fd_zero將指定的fd_set清零,然後呼叫巨集fd_set將需要測試的fd加入fd_set,接著呼叫函式select測試fd_set中的所有fd,最後用巨集fd_isset檢查某個fd在函式select呼叫後,相應位是否仍然為1。

以下是乙個測試單個檔案描述字可讀性的例子:

int  isready(int  fd)

下面還有乙個複雜一些的應用:

//這段**將指定測試socket的描述字的可讀可寫性,因為socket使用的也是fd

unit32  socketwait(tsocket* s,  bool rd,  bool wr,  unit32 timems);}

linux下的Select函式

part1 fd set errorfds同上面兩個引數的意圖,用來監視檔案錯誤異常。struct timeval timeout是select的超時時間,這個引數至關重要,它可以使select處於三種狀態,第一,若將null以形參傳入,即不傳入時間結構,就是將select置於阻塞狀態,一定等到監視...

Linux下select 系統呼叫

一 select 函式功能 select系統呼叫允許程式同時在多個底層檔案表述符上,等待輸入的到達或輸出的完成。二 函式意義 乙個伺服器可以同時在多個開啟的套接字等待請求到來的方法而處理多個客戶。只是具體應用的其中之一 自己的理解,但凡是程式在執行過程中會遇到阻塞 不到條件發生就不往下執行 的情況,...

linux下select函式的使用

先看下列的例子程式 include include include include define stdin 0 define true 1 define false 0 define ulong unsigned long static struct timeval timelast static...