select函數

select函數:程序員

http://baike.baidu.com/view/3421856.htm編程

 

select函數

 

概況

select()的機制中提供一fd_set的 數據結構,其實是一long類型的 數組, 每個數組元素都能與一打開的 文件句柄(無論是Socket句柄,仍是其餘 文件或 命名管道或設備句柄)創建聯繫,創建聯繫的工做由 程序員完成, 當調用select()時,由 內核根據IO狀態修改fd_set的內容,由此來通知執 行了select()的進程哪一Socket或文件可讀。
阻塞式I/O編程有兩個特色:
1、若是一個發現I\O有輸入,讀取的過程當中,另一個也有了輸入,這時候不會產生任何反應.這就須要你的程序語句去用到select函數的時候才知道有數據輸入。
2、程序去select的時候,若是沒有數據輸入,程序會一直等待,直到有數據爲止,也就是程序中無需循環和sleep。
Select在Socket編程中仍是比較重要的,但是對於初學 Socket的人來講都不太愛用Select寫程序,他們只是習慣寫諸如connect、accept、recv或recvfrom這樣的阻塞程序(所謂阻塞方式block,顧名思義,就是進程或是線程執行到這些函數時必須等待某個事件的發生,若是事件沒有發生,進程或線程就被阻塞,函數不能當即返回)。
但是使用Select就能夠完成非阻塞(所謂非阻塞方式non-block,就是進程或線程執行此函數時沒必要非要等待事件的發生,一旦執行確定返回,以返回值的不一樣來反映函數的執行狀況,若是事件發生則與阻塞方式相同,若事件沒有發生,則返回一個代碼來告知事件未發生,而進程或線程繼續執行,因此效率較高)方式工做的程序,它可以監視咱們須要監視的文件描述符的變化狀況——讀寫或是異常。
返回值:準備就緒的描述符數,若超時則返回0,若出錯則返回-1。

編輯本段操做程序

下面具體解釋:
#include < sys/types.h>
#include <sys/times.h>
#include <sys/select.h>
int select(nfds, readfds, writefds, exceptfds, timeout)
int nfds;
fd_set *readfds, *writefds, *exceptfds;
struct timeval *timeout;
ndfs:select監視的 文件句柄數,視進程中打開的文件數而定,通常設爲你要監視各文件
中的最大文件號加一。
readfds:select監視的可讀 文件句柄集合。
writefds: select監視的可寫 文件句柄集合。
exceptfds:select監視的異常 文件句柄集合。
timeout:本次select()的超時結束時間。(見/usr/sys/select.h,可精確至百萬分之一秒!)
當readfds或writefds中映象的文件可讀或可寫或超時,本次select()
就結束返回。程序員利用一組系統提供的宏在select()結束時即可判
斷哪一文件可讀或可寫,對Socket編程特別有用的就是readfds。

編輯本段宏解釋

幾行相關的宏解釋以下:
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, fd_set *fdset):檢查fdset聯繫的 文件句柄fd是否
可讀寫,當>0表示可讀寫。
(關於fd_set及相關宏的定義見/usr/include/ sys/types.h

編輯本段socket讀寫

這樣,你的socket只需在有東東讀的時候纔讀入,大體以下:
...
int sockfd;
fd_set fdR;
struct timeval timeout = ..;
...
for(;;) {
FD_ZERO(&fdR);
FD_SET(sockfd, &fdR);
switch (select(sockfd + 1, &fdR, NULL, NULL , &timeout)) {
case -1:
error handled by u;
case 0:
timeout hanled by u;
default:
if (FD_ISSET(sockfd, &fdR)) {
now u read or recv something;
/* if sockfd is father and
server socket, u can now
accept() */
}
}
}
因此一個FD_ISSET(sockfd)就至關通知了sockfd可讀。
至於struct timeval在此的功能,請man select。不一樣的timeval設置
使select()表現出超時結束、無超時阻塞和輪詢三種特性。因爲
timeval可精確至百萬分之一秒,因此Windows的SetTimer()根本不算
什麼。你能夠用select()作一個超級時鐘。
 
 
開放分類:
技術 軟件 操做系統
 
 
 
 

百度百科中的詞條正文與判斷內容均由用戶提供,不表明百度百科立場。若是您須要解決具體問題(如法律、醫學等領域),建議您諮詢相關領域專業人士。數據結構

142
相關文章
相關標籤/搜索