linux select函式學習

2021-08-27 06:13:04 字數 2710 閱讀 6020

1. i/o多路轉接

如果我們想從多個檔案描述符讀或寫資料,如果我們用以前學過的函式(read,write等)去處理可能會阻塞在乙個檔案描述符上,不能處理其他的檔案描述符。那是因為我們以前學的i/o處理函式,都是阻塞的i/o處理函式,它們的特點是,如果緩衝區裡有資料它們就會把資料寫到檔案中,如果快取區沒有資料他們就會等待(阻塞)直到有資料可讀。這就造成了他們無法對多個檔案描述符進行操作。而對多個檔案描述符進行操作在網路通訊方面卻是執關重要的。

一種比較好的解決方案就是i/o多路轉接技術。它現構造一張有關檔案描述符的列表,然後呼叫乙個函式,直到這些描述符中的乙個已經準備好進行i/o時,該函式才返回。在返回時,它告訴程序那些描述符已經準備好可以進行i/o。poll,selsct,pselect這三個函式使我們能夠執行i/o多路轉接,下面就分別介紹它們。

2.名稱::

select

功能:指行i/o多路轉接

標頭檔案:

#include

函式原形:

int select(int maxfdpl,fd_set *restrict readfds,fd_set *restrict writefds,fd_set *testrict exceptfds,struct timeval *testrict tvptr);

引數:maxfdpl最大描述符加1

readfds讀描述符集

writefds寫描述符集

excepfds異常描述符集

tvptr願意等待的時間

返回值:

準備就緒的檔案描述符數,若超時則返回0,若出錯則返回-1

select函式使我們可以執行i/o多路轉接。傳向select的引數告訴核心:我們所關係的描述符。對於每個描述符我們所關心的狀態。以及我們願意等待的時間。從select返回時,核心告訴我們:以準備好的描述符的數量。對於讀、寫或異常這三個狀態中的每乙個,那些描述符已經準備好。

這個函式比較複雜,我們乙個乙個引數的看。

第乙個引數maxfdp1的意思是「最大描述符加1」。也可將第乙個引數設定為fd_setsize,這是中的乙個常數,它說明了最大的描述符數(經常是1024)。如果將第三個引數設定為我們所關注的最大描述符編號值加一,核心就只需在此範圍內尋找開啟的位,而不必在三個描述符集中的數百位內搜尋。

中間的三個引數readfds、writefds和exceptfds是指向描述符集的指標。這三個描述符集說明了我們關心的可讀(readfds)、可寫(writefd)或處於異常條件(wxcepfds)的各個描述符。每個描述符集存放在乙個fd_set資料型別中。這種結構相當於乙個描述符的陣列,它為每個可能的描述符設定1位。

fd0fd1fd2fd3fdn00

00…readfdsà

fd0fd1fd2fd3fdn00

00…writefdsà

fd0fd1fd2fd3fdn00

00…excepfdsà

可用下面4個函式對描述符集進行操作。

select的中間三個引數中的任意乙個或全部都可以是空指標,這表示對相應狀態不關係。如果所有三個指標都是空指標,則select提供了較sleep更精確的計時器。其等待時間可以小於1秒。

tuptr指定最後等待的時間,它的結構是:

struct timeval;

有三種情況:

(1) tvptr==null:永遠等待。如果捕捉到乙個訊號則中斷此無限等待。當所指定的描述符中的乙個已經準備好或捕捉到乙個訊號則返回。如果捕捉到乙個訊號,則select返回-1,errno設定為eintr.

(2) tvptr->tv_sec==0&&tvptr_usec==0完全不等待。測試所有的描述符並立即返回。這是得到多個描述符的狀態而不阻塞select函式的輪詢方法。

(3)tvptr->tv_sec!=0||tvptr_usec!=0等待指定的秒數或微秒數。當指定的描述符之一已準備好,或當指定的時間值已超過時立即返回。如果在超時還沒有乙個描述符準備好,則返回值是0。

3.名稱::

fd_isset/fd_clr/fd_set/fd_zero

功能:描述符集處理函式

標頭檔案:

#include

函式原形:

int fd_isset(int fd,fd_set *fdset);

void fd_clr(int fd,fd_set *fdset);

void fd_set(int fd,fd_set *fdset);

void fd_zero(fd_set *fdset);

引數:fdset描述符集

fd描述符

返回值:

若fd在描述符集中則返回非0值,否則返回0(fd_isset)

呼叫fd_zero將乙個指定的fd_set變數的所有位設定為0。呼叫fd_set設定乙個fd_set變數的指定位。呼叫fd_clr將一指定位清除。最後呼叫fd_isset測試一指定位是否設定。宣告了乙個描述符集後,必須用fd_zero清除其所有位,然後在其中設定我們關心的各個位。

下面是select函式實現i/o多路轉接的乙個例子

/*12_3.c*/

#include

#include

#include

#include

#include

int main()}}

程式執行後等待使用者輸入。如果使用者輸入程式就會把它列印到螢幕上。如果使用者在3秒鐘未輸入任何字元,程式就列印「time out!」.

本程式實現了乙個檔案描述符的非阻塞i/o。

linux select函式用法

select系統呼叫是用來讓我們的程式監視多個檔案控制代碼的狀態變化的。程式會停在select這裡等待,直到被監視的檔案控制代碼有乙個或多個發生了狀態改變。關於檔案控制代碼,其實就是乙個整數,我們最熟悉的控制代碼是0 1 2三個,0是標準輸入,1是標準輸出,2是標準錯誤輸出。0 1 2是整數表示的,...

linux select函式用法

select系統呼叫是用來讓我們的程式 監視多個檔案控制代碼的狀態變化的。程式會停在select這裡等待,直到被監視的檔案控制代碼有乙個或多個發生了狀態改變。關於檔案控制代碼,其實就是乙個整數,我們最熟悉的控制代碼是0 1 2三個,0是標準輸入,1是標準輸出,2是標準錯誤輸出。0 1 2是整數表示的...

Linux select函式詳解

我們所關心的檔案描述符 對每個描述符,我們所關心的狀態。我們是要從乙個檔案描述符中讀或者寫,還是關注乙個描述符中是否出現異常 我們要等待多長時間。我們可以等待無限長的時間,等待固定的一段時間,或者根本就不等待 有了這些返回資訊,我們可以呼叫合適的i o函式 通常是read或 write 並且這些函式...