Linux 平臺 select 操作

Linux 平臺 select 操作

#include <sys/select.h>

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

void FD_CLR(int fd, fd_set *set);
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set)

select() 操作用于程序監(jiān)控相應(yīng)的文件描述符(file descriptor扁耐,fd)是否準(zhǔn)備好,即能否進(jìn)行無阻塞地讀取操作黄鳍。

文件描述符集(file descriptor set边器,fds)是函數(shù)最主要的參數(shù),它是一個 fd_set 類型的結(jié)構(gòu)體再膳,里面可以存儲最大 FD_SETSIZE(1024) 個 fd。為了安全地操作 fds曲横,系統(tǒng)提供了相應(yīng)的宏:

  • void FD_ZERO(fd_set *set) - 用于清空 fds 里存儲的 fd喂柒,一般在初始化時清空 fds 。
  • void FD_SET(int fd, fd_set *set) - 用于向 fds 里添加一個 fd 禾嫉。
  • void FD_CLR(int fd, fd_set *set) - 用于從 fds 里清除一個 fd 灾杰。
  • int FD_ISSET(int fd, fd_set *set) - 用于判斷 fd 是否在 fds 里,一般在 select() 調(diào)用結(jié)束之后使用熙参。

函數(shù)參數(shù)有三個 fds:

fds 函數(shù)調(diào)用前 函數(shù)調(diào)用后
readfds 監(jiān)聽 readfds 里的 fd 是否有可讀的 可無阻塞讀的 fd
writefds 監(jiān)聽 writefds 里的 fd 是否有可寫的 可無阻塞寫的 fd
exceptfds 監(jiān)聽 exceptfds 里的 fd 是否有發(fā)送異常的(一般未使用) 發(fā)生異常的 fd

select() 函數(shù)內(nèi)部會修改 readfds, writefds 和 exceptfds 內(nèi)存儲的 fd艳吠,函數(shù)返回時這些 fds 內(nèi)存儲的是可以進(jìn)行相應(yīng)操作的 fd 。因此若希望在一個 loop 里重復(fù)監(jiān)聽某一個 fd尊惰,需要每次調(diào)用 select() 之前重新設(shè)置 fds 讲竿。

函數(shù)參數(shù) nfds 是三個 fds 里序號最大的 fd 的序號值 + 1 。

timeout 是一個struct timeval 的結(jié)構(gòu)體指針弄屡,它代表希望阻塞等待的時間。函數(shù)返回時鞋诗,Linux 平臺下的 timeout 會被重寫膀捷,用于存儲阻塞剩余未使用的時間,而其他平臺的實現(xiàn)一般不會這樣做削彬。因此考慮到兼容性全庸,一般認(rèn)為 select() 返回后秀仲,timeout 對象就沒用了,下次調(diào)用 select() 需要重新初始化 timeout 壶笼。

struct timeval {
    time_t      tv_sec;         /* seconds */
    suseconds_t tv_usec;        /* microseconds */
};
  • 當(dāng)傳入的 timeout 里的字段值大于 0 神僵,select() 函數(shù)阻塞相應(yīng)的時間。當(dāng)一個 fd 準(zhǔn)備好覆劈,被信號處理中斷保礼,以及阻塞時間超時時,函數(shù)返回责语。
  • 當(dāng)傳入的 timeout 里的 tv_sectv_usec 都為 0 時炮障,select() 函數(shù)立即返回,用于輪詢的場景坤候。
  • 當(dāng)傳入的 timeout 為 NULL 時胁赢,select() 永久阻塞,直到有 fd 準(zhǔn)備好白筹。

函數(shù)返回值可以為:

  • EBADF - 錯誤的 fd 智末。
  • EINTR - 捕獲到信號。
  • EINVAL - nfds 為負(fù)數(shù)或大于 RLIMIT_NOFILE 的限制徒河,timeout 的值不合理系馆。
  • ENOMEN - 函數(shù)內(nèi)部動態(tài)分配內(nèi)存失敗。

一個 demo 如下虚青,簡單地監(jiān)控標(biāo)準(zhǔn)輸入:

#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>

int main(void)
{
    fd_set rfds;
    struct timeval tv;
    int retval;

    /* Watch stdin (fd 0) to see when it has input. */
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);

    /* Wait up to five seconds. */
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    retval = select(1, &rfds, NULL, NULL, &tv);
    /* Don't rely on the value of tv now! */

    if (retval == -1)
        perror("select()");
    else if (retval)
        printf("Data is available now.\n");
    /* FD_ISSET(0, &rfds) will be true. */
    else
        printf("No data within five seconds.\n");

    exit(EXIT_SUCCESS);
}

無任何輸入場景:

tangjia@FA001334:~/Jackistang$ ./tmp 
No data within five seconds.

輸入數(shù)據(jù)場景:

tangjia@FA001334:~/Jackistang$ ./tmp 
123456798
Data is available now.

參考:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末它呀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子棒厘,更是在濱河造成了極大的恐慌纵穿,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奢人,死亡現(xiàn)場離奇詭異谓媒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)何乎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門句惯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人支救,你說我怎么就攤上這事抢野。” “怎么了各墨?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵指孤,是天一觀的道長。 經(jīng)常有香客問我,道長恃轩,這世上最難降的妖魔是什么结洼? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮叉跛,結(jié)果婚禮上松忍,老公的妹妹穿的比我還像新娘。我一直安慰自己筷厘,他們只是感情好鸣峭,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著敞掘,像睡著了一般叽掘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玖雁,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天更扁,我揣著相機(jī)與錄音,去河邊找鬼赫冬。 笑死浓镜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的劲厌。 我是一名探鬼主播膛薛,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼补鼻!你這毒婦竟也來了哄啄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤风范,失蹤者是張志新(化名)和其女友劉穎咨跌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硼婿,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡锌半,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了寇漫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刊殉。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖州胳,靈堂內(nèi)的尸體忽然破棺而出记焊,到底是詐尸還是另有隱情,我是刑警寧澤栓撞,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布亚亲,位于F島的核電站,受9級特大地震影響腐缤,放射性物質(zhì)發(fā)生泄漏捌归。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一岭粤、第九天 我趴在偏房一處隱蔽的房頂上張望惜索。 院中可真熱鬧,春花似錦剃浇、人聲如沸巾兆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽角塑。三九已至,卻和暖如春淘讥,著一層夾襖步出監(jiān)牢的瞬間圃伶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工蒲列, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留窒朋,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓蝗岖,卻偏偏與公主長得像侥猩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子抵赢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容