重要區別
select函數在Linux和Windows下的區別主要是第一個參數“int n”,使用時需要特別注意。Linux下的“n”爲所有設備描述符的最大值加一,即 n = fdmax +1,當然,這裏 n 直接設置一個很大的值也行(比如1024);而Windows這個參數可以隨意,默認賦值爲 n = 0 即可。這裏很容易理解,但是在Linux編程時混淆的話,後果還是很嚴重的。
Linux下select函數詳解
要包含的頭文件
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
函數原型
int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout);
相關函數與功能介紹
FD_CLR(inr fd,fd_set* set); //將一個給定的文件描述符從集合中刪除
FD_ISSET(int fd,fd_set *set);//檢查集合中指定的文件描述符是否可以讀寫
FD_SET(int fd,fd_set*set); //將一個給定的文件描述符加入集合之中
FD_ZERO(fd_set *set); //用來清除描述詞組set的所有位;
兩個重要結構體說明
struct fd_set 可以理解爲一個集合,這個集合中存放的是文件描述符(filedescriptor),即文件句柄。
struct timeval 是一個大家常用的結構,用來代表時間值,有兩個成員,一個是秒數,另一個是毫秒數。如下所示
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
時間結構體 timeout 可以使select處於三種狀態,第一,若將NULL以形參傳入,即不傳入時間結構,就是將select置於阻塞狀態,一定等到監視文件描述符集合中某個文件描述符發生變化爲止;第二,若將時間值設爲0秒0毫秒,就變成一個純粹的非阻塞函數,不管文件描述符是否有變化,都立刻返回繼續執行,文件無變化返回0,有變化返回一個正值;第三,timeout的值大於0,這就是等待的超時時間,即select在timeout時間內阻塞,超時時間之內有事件到來就返回了,否則在超時後不管怎樣一定返回,返回值如下。
返回值
零:等待超時,沒有可讀寫或錯誤的文件
負值:select錯誤
正值:某些文件可讀寫 ,一般返回的正值表示可讀寫的設備描述符的數量(這裏需要自己確認一下)
具體功能
select函數在Socket編程中還是比較重要的,它可以實現同時對對個文件活套接字描述符的監聽,如果監聽事件沒有發生阻塞(比如可讀)則阻塞,如果發生則執行相應的操作。通過select就能實現多樣化的功能,又不至於使處理器滿負荷運行。只有使用了select函數才能寫出像樣的網絡程序。