一、select函數說明
int select(int maxfd, fd_set *readset,fd_set *writeset, fd_set *exceptset,const struct timeval *timeout);
功能:指示內核等待多個事件中的任何一個發生,並只在有一個或多個事件發生或經歷一段指定時間後才喚醒參數:
maxfd:這是一個整數值,是指集合中所有文件描述符的範圍,即所有文件描述符的最大值加1
readset:可讀描述符集,指向fd_set結構的指針,監測該集合中的任意描述符是否有數據可讀,這個集合中應該包括文件描述符,我們是要監視這些文件描述符的讀變化的,即我們關心是否可以從這些文件中讀取數據了,如果這個集合中有一個文件可讀,select就會返回一個大於0的值,表示有文件可讀,如果沒有可讀的文件,則根據timeout參數再判斷是否超時,若超出timeout的時間,select返回0,若發生錯誤返回負值。
writeset:可寫描述符集,監測該集合中的任意描述符是否有數據可寫,同上
exceptset:異常描述符集,監測該集合中的任意描述符是否發生異常,同上
timeout:超時時間,具體有三種情況,第一:若將NULL以形參傳入,即不傳入時間結構,就是將select置於阻塞狀態,一定等到監視文件描述符集合中某個文件描述符發生變化爲止;第二:若將時間值設爲0秒0毫秒,就變成一個純粹的非阻塞函數,不管文件描述符是否有變化,都立刻返回繼續執行,文件無變化返回0,有變化返回一個正值;第三:timeout的值大於0,這就是等待的超時時間,即select在timeout時間內阻塞,超時時間之內有事件到來就返回了,否則在超時後不管怎樣一定返回,返回值同上述。
返回值:0 => 超時,-1 => 出錯:正數(>0) => 準備好的描述符數量
頭文件:#include <sys/select.h>,#incldue <sys/time.h>
二、補充說明兩個結構體:
<1> struct fd_set可以理解爲一個集合,這個集合中存放的是文件描述符(file descriptor),即文件句柄,這可以是我們所說的普通意義的文件,當然Unix下任何設備、管道、FIFO等都是文件形式,全部包括在內,所以,毫無疑問,一個socket就是一個文件,socket句柄就是一個文件描述符。fd_set集合可以通過一些宏由人爲來操作,比如清空集合:FD_ZERO(fd_set*)、加入集合之中:FD_SET(int, fd_set*)、從集合中刪除:FD_CLR(int, fd_set*)、檢查集合:FD_ISSET(int, fd_set*)。
<2> struct timeval是一個大家常用的結構,用來代表時間值,有兩個成員,一個是秒數,另一個毫秒數。
struct timeval
{
long tv_sec; //秒
long tv_usec; //微秒
};
三、與select函數相關的幾個宏
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):監測fd文件描述符是否有事件發生(具體是什麼事件得看實際編程情況)