select函數用法詳解


1. select函數

select的作用:

輪詢的方式,從多個文件描述符中獲取狀態變化后的情況。

頭文件

#include <sys/time.h>   //for struct timeval
#include <unistd.h>     //for select

函數原型

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

參數解釋

  • nfds: 要檢測的文件描述符的范圍,為文件最大描述符+1
  • readfds: 包含所有可能因狀態變成可讀而觸發select函數返回的文件描述符
  • writefds: 包含所有可能因狀態變成可寫而觸發select函數返回的文件描述符
  • exceptfds: 包含所有可能因狀態發生異常而觸發select函數返回的文件描述符
void FD_CLR(int fd, fd_set *set);       //將fd在set中去除
void FD_SET(int fd, fd_set *set);       //將fd添加到set中
int  FD_ISSET(int fd, fd_set *set);     //檢查set中fd是否有狀態變化
void FD_ZERO(fd_set *set);              //清空整個set
  • timeout:
struct timeval {
     long    tv_sec;         /* seconds */
     long    tv_usec;        /* microseconds */
};

返回值
當超時或其中一個/多個文件描述符發生變化時,此函數將返回,返回值:

  • -1: 函數執行出錯
  • 0: 超時,並將時間結構體清空為0
  • 0: 狀態變化的文件描述符的個數

基本實例

fd_set rdfds;   
struct timeval tv;
int rtn = 0;

FD_ZERO(&rdfds);     //清空fd_set
FD_SET(socket, &rdfds);  //將要檢測的socket描述符加入到fd_set集合中

tv.tv_sec = 2;
tv.tv_usec = 1000;      //設置超時時間為2s+1ms

rtn = select(socket+1, &rdfds, NULL, NULL, &tv);

if(rtn < 0)
    perror("select");
else if(0 == rtn)
    printf("timeout\n");
else
{
    printf("rtn = %d\n", rtn);      //查看有多少個文件描述符發生了變化
    
    if(FD_ISSET(socket, &rdfds))    //判斷下這個socket是否狀態真的變成了可讀
    {
        recv(...);
    }
}

2. select做時間函數

void time_delay(int seconds)
{ 
    struct timeval tv;
    int err;
    
    tv.tv_sec = seconds;     //超時時間
    tv.tv_usec = 0;
    
    do
    {
       err = select(0,NULL,NULL,NULL,&tv);  //將nfds設置為0即為超時函數
    }while(err<0 && errno==EINTR);          //
}

3. 未完待續


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM