1. 程式人生 > >select函式詳細用法解析

select函式詳細用法解析

1.表頭檔案

#include

#include

#include

2.函式原型

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

3.函式說明

select()用來等待檔案描述詞狀態的改變。引數n代表最大的檔案描述詞加1,引數readfdswritefdsexceptfds 稱為描述片語,是用來回傳該描述詞的讀,寫或例外的狀況。底下的巨集提供了處理這三種描述片語的方式:

FD_CLR(inr fd,fd_set* set);用來清除描述片語set

中相關fd的位

FD_ISSET(int fd,fd_set *set);用來測試描述片語set中相關fd的位是否為真

FD_SETint fd,fd_set*set);用來設定描述片語set中相關fd的位

FD_ZEROfd_set *set);用來清除描述片語set的全部位

4.結構體說明

先說明兩個結構體:
1) struct fd_set可以理解為一個集合,這個集合中存放的是檔案描述符(filedescriptor),即檔案控制代碼,這可以是我們所說的普通意義的檔案,當然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

{

time_t tv_sec;

time_t tv_usec;

};


5. 具體引數說明:
   1) int n:
是一個整數值,是指集合中所有檔案描述符的範圍,即所有檔案描述符的最大值加1,不能錯!在Windows中這個引數的值無所謂,可以設定不正確。
    2) fd_set*readfds
是指向fd_set結構的指標,這個集合中應該包括檔案描述符,我們是要監視這些檔案描述符的讀變化的,即我們關心是否可以從這些檔案中讀取資料了,如果這個集合中有一個檔案可讀,select就會返回一個大於0的值,表示有檔案可讀,如果沒有可讀的檔案,則根據timeout引數再判斷是否超時,若超出timeout的時間,select返回0,若發生錯誤返回負值。可以傳入NULL值,表示不關心任何檔案的讀變化。
     3) fd_set*writefds
是指向fd_set結構的指標,這個集合中應該包括檔案描述符,我們是要監視這些檔案描述符的寫變化的,即我們關心是否可以向這些檔案中寫入資料了,如果這個集合中有一個檔案可寫,select就會返回一個大於0的值,表示有檔案可寫,如果沒有可寫的檔案,則根據timeout引數再判斷是否超時,若超出timeout的時間,select返回0,若發生錯誤返回負值。可以傳入NULL值,表示不關心任何檔案的寫變化。
     4) fd_set *errorfds
同上面兩個引數的意圖,用來監視檔案錯誤異常。
     5)struct timeval *timeout
select的超時時間,這個引數至關重要,它可以使select處於三種狀態,第一,若將NULL以形參傳入,即不傳入時間結構,就是將select置於阻塞狀態,一定等到監視檔案描述符集合中某個檔案描述符發生變化為止;第二,若將時間值設為00毫秒,就變成一個純粹的非阻塞函式,不管檔案描述符是否有變化,都立刻返回繼續執行,檔案無變化返回0,有變化返回一個正值;第三,timeout的值大於0,這就是等待的超時時間,即selecttimeout時間內阻塞,超時時間之內有事件到來就返回了,否則在超時後不管怎樣一定返回,返回值同上述。
6
.返回值

負值:select錯誤

正值:某些檔案可讀寫或出錯 0:等待超時,沒有可讀寫或錯誤的檔案

如果引數timeout設為NULL則表示select()沒有timeout

7.錯誤程式碼

執行成功則返回檔案描述詞狀態已改變的個數,如果返回0代表在描述詞狀態改變前已超過timeout時間,當有錯誤發生時則返回-1,錯誤原因存於errno,此時引數readfdswritefdsexceptfdstimeout的值變成不可預測。

EBADF 檔案描述詞為無效的或該檔案已關閉

EINTR 此呼叫被訊號所中斷

EINVAL 引數n為負值。

ENOMEM 核心記憶體不足

8.範例

1) 在標準輸入讀取9個位元組資料。

select函式實現超時判斷!

int main(int argc, char ** argv)

{

char buf[10] = "";

fd_set rdfds;//

struct timeval tv; //store timeout

int ret; // return val

FD_ZERO(&rdfds); //clear rdfds

FD_SET(1, &rdfds); //add stdin handle into rdfds

tv.tv_sec = 3;

tv.tv_usec = 500;

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

if(ret < 0)

perror("\nselect");

else if(ret == 0)

printf("\ntimeout");

else

{

printf("\nret=%d", ret);

}

if(FD_ISSET(1, &rdfds))

{

printf("\nreading");

fread(buf, 9, 1, stdin); // read form stdin

}

// read(0, buf, 9); /* read from stdin */

// fprintf(stdout, "%s\n", buf); /* write to stdout */

write(1, buf, strlen(buf)); //write to stdout

printf("\n%d\n", strlen(buf));

return 0;

}

2) 從網路上接受資料寫入一個檔案中。
main()
{
    int sock;
    FILE *fp;
    struct fd_set fds;
    struct timeval timeout={3,0}; //select
等待3秒,3秒輪詢,要非阻塞就置0
    char buffer[256]={0}; //256
位元組的接收緩衝區
    /*
假定已經建立UDP連線,具體過程不寫,簡單,當然TCP也同理,主機ipport都已經給定,要寫的檔案已經開啟
    sock=socket(...);
    bind(...);
    fp=fopen(...); */
    while(1)
   {
        FD_ZERO(&fds); //
每次迴圈都要清空集合,否則不能檢測描述符變化
        FD_SET(sock,&fds); //
新增描述符
        FD_SET(fp,&fds); //
同上
        maxfdp=sock>fp?sock+1:fp+1;    //
描述符最大值加1
        switch(select(maxfdp,&fds,&fds,NULL,&timeout))   //select
使用
        {
            case -1: exit(-1);break; //select
錯誤,退出程式
            case 0:break; //
再次輪詢
            default:
                  if(FD_ISSET(sock,&fds)) //
測試sock是否可讀,即是否網路上有資料
                  {
                        recvfrom(sock,buffer,256,.....);//
接受網路資料
                        if(FD_ISSET(fp,&fds)) //
測試檔案是否可寫
                            fwrite(fp,buffer...);//
寫入檔案
                         buffer
清空;
                   }// end if break;
          }// end switch
     }//end while
}//end main

相關推薦

select函式詳細用法解析

1.表頭檔案 #include #include #include 2.函式原型 int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeo

select函式詳細用法解析(轉自:zhenhuaqin)

1.表頭檔案 #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <sys/select.h> 2.函式原型 int s

select函數詳細用法解析

集合 cep 返回值 null 毫無 文件中 str 個數 for 1.表頭文件 #include #include #include 2.函數原型 int select(int n,fd_set * readfds,fd_set * writefds,fd_set * e

Linux系統指令‘df’詳細用法解析

df-檢視不同的檔案系統有多少空閒的磁碟空間、被掛載檔案系統的磁碟利用率(僅以K顯示)。 df -h 以可讀的方式展示磁碟空間(會根據檔案大小以K,M,G直觀顯示) 展示inode使用情況:ino

signal函式詳細用法

傳智掃地僧課程學習筆記。 訊號是在軟體層次上對中斷的一種模擬,所以通常把它稱為是軟中斷 訊號和中斷的區別 訊號與中斷的相似點: (1)採用了相同的非同步通訊方式; (2)當檢測出有訊號或中斷請求時,都暫停正在執行的程式而轉去執行相應的處理程式; (3)都在處理完畢後

linux之select函式用法詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

【python】詳解map函式用法函式並行作用解析

Python函式程式設計中的map(func, seq1[, seq2,…]) 函式是將func作用於seq中的每一個元素,其中seq須是可迭代物件,並將所有的呼叫的結果作為一個list返回。如果func為None,作用同zip()。 本文參考自:Python中map()函式淺析一文,感謝精彩分享。 下面

scala-zipWithIndex、zipWithUniqueId 函式用法解析

1. 是什麼 顧名思義,zipWithIndex:通過主鍵打包,ZipWithUniqueId:通過唯一主鍵打包。二者的主要作用 1. def zipWithIndex(): RDD[(T, Long)] 該函式將RDD中的元素和這個元素在RDD中的ID(索引號

C語言常用庫函式(含詳細用法

一、數學函式 呼叫數學函式時,要求在原始檔中包下以下命令列: #include <math.h> 函式原型說明 功能 返回值 說明 int abs( int x) 求整數x的絕對值 計算結果 double fabs(double

linux之select函式解析

select()的機制中提供一fd_set的資料結構,實際上是一long型別的陣列, 每一個數組元素都能與一開啟的檔案控制代碼(不管是Socket控制代碼,還是其他 檔案或命名管道或裝置控制代碼)建立聯絡,建立聯絡的工作由程式設計師完成, 當呼叫select()時,由核心根

《機器學習實戰》(第二章)中函式詳細解析

本文是針對《機器學習實戰》內函式的解析。並以頁數呈現。 P19:numpy.tile(A,rep)函式 當rep為數字時,生成一個一維重複rep次的list。 當rep為元組(m,n)時,生成一個m行並且每行重複n次的矩陣。 import numpy as np a1

List詳細用法與原理解析

List是Collection介面的子介面,他可以定義一個允許重複的線性集合,即允許存放相同的元素,但是存放的位置不同。與collection不同的是,List新增了列表迭代器ListInterator。 與Collection介面相比,List介面新增瞭如下方法: a

Python3中高階函式lambda,filter,map,reduce,zip的詳細用法

在Python裡有五大高階函式,他們分別是lambda()匿名函式,filter()篩選函式,map()函式,reduce()函式,zip()函式。下面就讓我們來詳細的瞭解一下這五種函式的具體用法吧。 1.lambda()匿名函式 匿名函式lambda:是指一類無需定義識別符號(函式名)的函式或子程式。

深入解析array_merge函式用法 php (轉)

array_merge是我們用來合併陣列使用最多的函式; 下面就來深入解析array_merge的用法; 第四點是個坑需注意; 1:如果陣列中有相同的字串鍵名; 則該鍵名後面的值覆蓋前面的值; 如果想讓前面的值覆蓋後面; 則可以使用+號; &nbs

thinkphp U方法 U函式詳細解析

U方法用於完成對URL地址的組裝,特點在於可以自動根據當前的URL模式和設定生成對應的URL地址,格式為:U('地址','引數','偽靜態','是否跳轉','顯示域名'); 在模板中使用U方法而不是固定寫死URL地址的好處在於,一旦你的環境變化或者引數設定改變,你不需要更改模

I/O複用模型之select函式用法——伺服器開發

現在我們介紹另外一種常用併發伺服器開發的技術——select函式I/O複用模型。 先來介紹select及相關的函式: select函式的作用是監聽指定的多個I/O的檔案描述符,在設定的時間內阻塞,當有一個或者多個I/O埠滿足某個“讀”或者“寫”的條件,則在fd_set型別

linux select函式用法

轉載:http://blog.csdn.net/liujia2100/article/details/9004750?locationNum=1&fps=1 Select可以監控多個檔案控制代碼,監控檔案內容的變化,比如可讀可寫狀態的改變,利用select可以

一:Vue中的join(),reverse()與 split()函式用法解析

Html<div id="app-5"> <p>{{ message }}</p> <button v-on:click="reverseMessage

socket select函式詳細講解

原型 int select(int nfds,fd_set* ,fd_set* ,fd_set* ,const struct timeval* ); nfds:本引數忽略,僅起到相容作用。   readfds:(可選)指標,指向一組等待可讀性檢查的套介面。   writefds:(可選)指標,指向一組等待可

OCP-1Z0-051 第96題 NVL2函式詳細用法

Examine the structure of the INVOICE table.name                Null           Type INV_NO             NOT NULL       NUMBER(3) INV_DATE