檔案頭:#include<sys/select.h>
int select (int maxfdp1,fd_set * restrict readfds,fd_set *restrict writefds,fdset *restrict exceptfds,struct timeval *restrict tvptr);
傳回值:準備就緒的描述符數,若逾時則返回0,若出錯,返回-1.但是要注意:如果在一個描述符上碰到了檔案結尾處,則select認為改描述符是可讀的,然後調用read,返回0。
注意:select中間有三個參數,如果三個指標都為空白,則select提供了比sleep更為精確的計時器。
select 函數使我們可以執行I/O多路轉接。傳向select的參數告訴核心:
1.我們所關心的描述符;
2.對於每個描述符我們所關心的狀態;
3.願意等待多長時間(永遠tvptr=NULL、固定值tvptr->tv_sec!=0||tvptr->tv_sec!=0、不等待tvptr->tv_sec==0&&tvptr->tv_usec==0)。
從select返回是,核心告訴我們:
對於讀、寫、異常這三個狀態中的每一個,哪個描述符已經準備好了。”準備好“是指:對於readfds的read不會阻塞,則此描述符準備好。對於wirtefds的write操作不會阻塞,則此描述符準備好。exceptfds有未決異常,則準備好。
maxfdp1:select監視的檔案控制代碼數,視進程中開啟的檔案數而定,一般設為要監視各檔案中的最大檔案號加一。 因為描述符編號是從0開始的,所以描述符(個)數要再編號基礎上+1.
readfds:select監視的可讀檔案控制代碼集合。
writefds: select監視的可寫檔案控制代碼集合。
exceptfds:select監視的異常檔案控制代碼集合。
每個描述符集存放在一個fd_set資料類型中。
FD_ZERO(fd_set *fdset):清空fdset與所有檔案控制代碼的聯絡。
FD_SET(int fd, fd_set *fdset):建立檔案控制代碼fd與fdset的聯絡。
FD_CLR(int fd, fd_set *fdset):清除檔案控制代碼fd與fdset的聯絡。
FD_ISSET(int fd, fdset *fdset):檢查fdset聯絡的檔案控制代碼fd是否 可讀寫,>0表示可讀寫。
在聲明了一個描述符集合,必須用FD_ZERO清除其所用位,然後在其中設定我們關心的各個位。
例如:
fd_set rset;
int fd;
FD_ZERO(&rest);
FD_SET(fd,&rset);
FD_SET(STDIN_FILENO,&rset);
if(FD_ISSET(fd,&rset)){
......}
參考文獻:
UNIX環境進階編程(第二版)