国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Linux下select函數(shù)的用法

2023-03-29 11:11 作者:有AI野心的電工和碼農(nóng)  | 我要投稿

本文是十多年前利用網(wǎng)上搜集的資料拼接而成,這些內(nèi)容基本上一直也不會過時。

0. 函數(shù)定義

頭文件:

?


函數(shù)定義:

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

函數(shù)說明:

select()用來等待文件描述詞狀態(tài)的改變。參數(shù)n代表最大的文件描述詞加1,參數(shù)readfds、writefds 和exceptfds稱為描述詞組,是用來回傳該描述詞的讀,寫或例外的狀況。

底下的宏提供了處理這三種描述詞組的方式:

  • FD_CLR(inr fd, fd_set* set); 用來清除描述詞組set中相關(guān)fd的位

  • FD_ISSET(int fd, fd_set *set); 用來測試描述詞組set中相關(guān)fd的位是否為真

  • FD_SET(int fd, fd_set *set); 用來設(shè)置描述詞組set中相關(guān)fd的位

  • FD_ZERO(fd_set *set); 用來清除描述詞組set的全部位

參數(shù):

timeout為結(jié)構(gòu)timeval,用來設(shè)置select()的等待時間,其結(jié)構(gòu)定義如下

返回值:

如果參數(shù)timeout設(shè)為NULL則表示select()沒有timeout。

錯誤代碼:

執(zhí)行成功則返回文件描述詞狀態(tài)已改變的個數(shù),

如果返回0代表在描述詞狀態(tài)改變前已超過timeout時間,

當有錯誤發(fā)生時則返回-1,錯誤原因存于errno,此時參數(shù)readfds,writefds,exceptfds和timeout的值變成不可預(yù)測。

  • EBADF 文件描述詞為無效的或該文件已關(guān)閉

  • EINTR 此調(diào)用被信號所中斷

  • EINVAL 參數(shù)n為負值

  • ENOMEM 核心內(nèi)存不足

范例:

常見的程序片段:

1. Select函數(shù)詳細介紹

Select在Socket編程中還是比較重要的,可是對于初學Socket的人來說都不太愛用Select寫程序,他們只是習慣寫諸如connect、 accept、recv或recvfrom這樣的阻塞程序(所謂阻塞方式block,顧名思義,就是進程或是線程執(zhí)行到這些函數(shù)時必須等待某個事件的發(fā)生,如果事件沒有發(fā)生,進程或線程就被阻塞,函數(shù)不能立即返回)。

可是使用Select就可以完成非阻塞(所謂非阻塞方式non-block,就是進程或線程執(zhí)行此函數(shù)時不必非要等待事件的發(fā)生,一旦執(zhí)行肯定返回,以返回值的不同來反映函數(shù)的執(zhí)行情況,如果事件發(fā)生則與阻塞方式相同,若事件沒有發(fā)生則返回一個代碼來告知事件未發(fā)生,而進程或線程繼續(xù)執(zhí)行,所以效率較高)方式工作的程序,它能夠監(jiān)視我們需要監(jiān)視的文件描述符的變化情況--讀寫或是異常。

下面詳細介紹一下:

Select的函數(shù)格式(我所說的是Unix系統(tǒng)下的伯克利socket編程,和windows下的有區(qū)別,一會兒說明):

int select(int maxfdp, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);

1.1 先說明兩個結(jié)構(gòu)體

一.?struct fd_set

可以理解為一個集合,這個集合中存放的是文件描述符(filedescriptor),即文件句柄,這可以是我們所說的普通意義的文件,當然Unix下任何設(shè)備、管道、FIFO等都是文件形式,全部包括在內(nèi),所以毫無疑問一個socket就是一個文件,socket句柄就是一個文件描述符。

fd_set集合可以通過一些宏由人為來操作,比如:

  • FD_ZERO(fd_set *);?清空集合

  • FD_SET(int, fd_set *);?將一個給定的文件描述符加入集合之中

  • FD_CLR(int, fd_set *);?將一個給定的文件描述符從集合中刪除

檢查集合中指定的文件描述符是否可以讀寫FD_ISSET(int ,fd_set* )一會兒舉例說明。

二.?struct timeval

是一個大家常用的結(jié)構(gòu),用來代表時間值,有兩個成員,一個是秒數(shù),另一個是毫秒。

1.2 具體解釋select的參數(shù)

  • int maxfdp:是一個整數(shù)值,是指集合中所有文件描述符的范圍,即所有文件描述符的最大值加1,不能錯!?在Windows中這個參數(shù)的值無所謂,可以設(shè)置不正確。

  • fd_set* readfds:是指向fd_set結(jié)構(gòu)的指針,這個集合中應(yīng)該包括文件描述符,我們是要監(jiān)視這些文件描述符的讀變化的,即我們關(guān)心是否可以從這些文件中讀取數(shù)據(jù)了,如果這個集合中有一個文件可讀,select就會返回一個大于0的值,表示有文件可讀,如果沒有可讀的文件,則根據(jù)timeout參數(shù)再判斷是否超時,若超出timeout的時間,select返回0,若發(fā)生錯誤返回負值。可以傳入NULL值,表示不關(guān)心任何文件的讀變化。

  • fd_set* writefds:是指向fd_set結(jié)構(gòu)的指針,這個集合中應(yīng)該包括文件描述符,我們是要監(jiān)視這些文件描述符的寫變化的,即我們關(guān)心是否可以向這些文件中寫入數(shù)據(jù)了,如果這個集合中有一個文件可寫,select就會返回一個大于0的值,表示有文件可寫,如果沒有可寫的文件,則根據(jù)timeout參數(shù)再判斷是否超時,若超出timeout的時間,select返回0,若發(fā)生錯誤返回負值。可以傳入NULL值,表示不關(guān)心任何文件的寫變化

  • fd_set * errorfds:同上面兩個參數(shù)的意圖,用來監(jiān)視文件錯誤異常

  • struct timeval* timeout:是select的超時時間,這個參數(shù)至關(guān)重要,它可以使select處于三種狀態(tài):

第一,若將NULL以形參傳入,即不傳入時間結(jié)構(gòu),就是將select置于阻塞狀態(tài),一定等到監(jiān)視文件描述符集合中某個文件描述符發(fā)生變化為止;

第二,若將時間值設(shè)為0秒0毫秒,就變成一個純粹的非阻塞函數(shù),不管文件描述符是否有變化,都立刻返回繼續(xù)執(zhí)行,文件無變化返回0,有變化返回一個正值;

第三,timeout的值大于0,這就是等待的超時時間,即select在timeout時間內(nèi)阻塞,超時時間之內(nèi)有事件到來就返回了,否則在超時后不管怎樣一定返回,返回值同上述。

1.3 select 返回值

  • 負值:select錯誤

  • 正值:某些文件可讀寫或出錯

  • 0:等待超時,沒有可讀寫或錯誤的文件

2. 例子

在有了select后可以寫出像樣的網(wǎng)絡(luò)程序來!

舉個簡單的例子,就是從網(wǎng)絡(luò)上接受數(shù)據(jù)寫入一個文件中。

用來循環(huán)讀取鍵盤輸入的例子:

將例子程序作一修改,加上了time out,并且考慮了select得所有的情況:


Linux下select函數(shù)的用法的評論 (共 條)

分享到微博請遵守國家法律
逊克县| 南江县| 平遥县| 睢宁县| 宁强县| 浙江省| 海门市| 土默特左旗| 沙洋县| 二手房| 温宿县| 湘乡市| 安塞县| 宁晋县| 新竹县| 嵩明县| 包头市| 花莲市| 毕节市| 志丹县| 平定县| 隆德县| 鄢陵县| 沅江市| 凤山县| 平乐县| 田东县| 岳阳市| 文登市| 武冈市| 梁山县| 宁波市| 佛学| 从化市| 洛宁县| 蚌埠市| 丘北县| 钟山县| 岑溪市| 讷河市| 安化县|