select函式及fd set介紹

2021-07-16 02:47:48 字數 1766 閱讀 7653

在程式設計的過程中,經常會遇到許多阻塞的函式,好像read和網路程式設計時使用的recv, recvfrom函式都是阻塞的函式,當函式不能成功執行的時候,程式就會一直阻塞在這裡,無法執行下面的**。這是就需要用到非阻塞的程式設計方式,使用select函式就可以實現非阻塞程式設計。

select函式是乙個輪循函式,迴圈詢問檔案節點,可設定超時時間,超時時間到了就跳過**繼續往下執行。

select需要驅動程式的支援,驅動程式實現fops內的poll函式。select通過每個裝置檔案對應的poll函式提供的資訊判斷當前是否有資源可用(如可讀或寫),如果有的話則返回可用資源的檔案描述符個數,沒有的話則睡眠,等待有資源變為可用時再被喚醒繼續執行。詳細的原理請看

這裡該函式宣告如下

int select(int nfds,  fd_set* readset,  fd_set* writeset,  fe_set* exceptset,  struct timeval* timeout);
引數:nfds           需要檢查的檔案描述字個數

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

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

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

timeout      超時,填null為阻塞,填0為非阻塞,其他為一段超時時間

返回值:

返回fd的總數,錯誤時返回socket_error

上面select函式中需要用到兩個fd_set形參,這個結構體到底做什麼用的呢

fd_set其實這是乙個陣列的巨集定義,實際上是一long型別的陣列,每乙個陣列元素都能與一開啟的檔案控制代碼(socket、檔案、管道、裝置等)建立聯絡,建立聯絡的工作由程式設計師完成,當呼叫select()時,由核心根據io狀態修改fd_set的內容,由此來通知執行了select()的程序哪個控制代碼可讀。

系統提供了fd_set, fd_clr, fd_isset, fd_zero進行操作,宣告如下:

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

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

fd_isset(int fd, fd_set *fdset); //檢測fd是否在set集合中,不在則返回0

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

下面寫一段程式**一下這幾個巨集的工作:

#include int main()

當使用fd_set新增完1、2、3、7後,fdset的值如下:

然後經過fd_clr以後,fd_array[2]就被清除了,陣列後面的資料依次往前提,即7被放到了fd_array[2]

所以isset前後兩次列印的值分別為1和0

select的結果會對fd_set造成影響。例如,對於乙個監聽的socket:

#include #include #pragma comment(lib,"ws2_32.lib")   

int main()

所以可以使用select以及fd的操作來完成非同步的網路訊息處理,具體的實現請看這裡的例

fd set 用法 select函式相關

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

Linux下select 機制中fd set用法

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

PHP原生處理select結果集的函式介紹

select mysql num rows result 從結果集中獲取資料記錄的個數 mysql num fields result 從結果集中獲取資料記錄列的個數 mysql fetch row 該函式將一條結果記錄返回,並以乙個普通索引陣列的形式儲存 mysql fetch assoc 該函式...