日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下IO多路复用之select函数的使用

發(fā)布時(shí)間:2023/11/30 linux 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下IO多路复用之select函数的使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

select函數(shù)的作用:

? ? 如果我們的程序里有兩個(gè)需要阻塞的地方,例如要從服務(wù)器讀數(shù)據(jù),同時(shí)還要從鍵盤上讀數(shù)據(jù)(若不采用阻塞而用查詢的方式則大量占用系統(tǒng)資源)。這個(gè)時(shí)候我們就有兩處阻塞,你當(dāng)然可以用多線程或多進(jìn)程的方法去解決,但我們今天介紹另外一個(gè)方法:I/O多路復(fù)用,如select,poll等機(jī)制,select它能夠監(jiān)視我們需要監(jiān)視的文件描述符的變化情況——讀寫或是異常。

頭文件: #include <sys/select.h>函數(shù)原型: int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

參數(shù):

1.int maxfdp是一個(gè)整數(shù)值,是指集合中所有文件描述符的范圍,即所有文件描述符的最大值加1,不能錯(cuò)!在Windows中這個(gè)? ? ? ?參數(shù)值無所謂,可以設(shè)置不正確。
2.fd_set* readfds是指向fd_set結(jié)構(gòu)的指針,這個(gè)集合中應(yīng)該包括文件描述符,我們是要監(jiān)視這些文件描述符的讀變化的,即我? ? 們關(guān)心是否可以從這些文件中讀取數(shù)據(jù)了,如果這個(gè)集合中有一個(gè)文件可讀,select就會(huì)返回一個(gè)大于0的值,表示有文件可讀,如果沒有可讀的文件,則根據(jù)timeout參數(shù)再判斷是否超時(shí),若超出timeout的時(shí)間,select返回0,若發(fā)生錯(cuò)誤返回負(fù)值。可以入NULL值,表示不關(guān)心任何文件的讀變化。
3.fd_set* writefds是指向fd_set結(jié)構(gòu)的指針,這個(gè)集合中應(yīng)該包括文件描述符,我們是要監(jiān)視這些文件描述符的寫變化的,即我們關(guān)心是否可以向這些文件中寫入數(shù)據(jù)了,如果這個(gè)集合中有一個(gè)文件可寫,select就會(huì)返回一個(gè)大于0的值,表示有文件可寫,如果沒有可寫的文件,則根據(jù)timeout再判斷是否超時(shí),若超出timeout的時(shí)間,select返回0,若發(fā)生錯(cuò)誤返回負(fù)值。可以傳入NULL值,表示不關(guān)心任何文件的寫變化。
4.fe_set* errorfds同上面兩個(gè)參數(shù)的意圖,用來監(jiān)視文件錯(cuò)誤異常。
5.struct timeval* timeout是select的超時(shí)時(shí)間,這個(gè)參數(shù)至關(guān)重要,它可以使select處于三種狀態(tài)。
???? ?第一:若將NULL以形參傳入,即不傳入時(shí)間結(jié)構(gòu),就是將select置于阻塞狀態(tài),一定等到監(jiān)視文件描述符集合中某個(gè)文件描述符發(fā)生變化為止;
???? ?第二:若將時(shí)間值設(shè)為0秒0毫秒,就變成一個(gè)純粹的非阻塞函數(shù),不管文件描述符是否有變化,都立刻返回繼續(xù)執(zhí)行,文件無變化返回0,有變化返回一個(gè)正值;
???? ?第三:timeout的值大于0,這就是等待的超時(shí)時(shí)間,即select在timeout時(shí)間內(nèi)阻塞,超時(shí)時(shí)間之內(nèi)有事件到來就返回了,否則在超時(shí)后不管怎樣一定返回,返回值同上述。

返回值:

? 負(fù)值:select錯(cuò)誤;
? 正值:某些文件可讀寫或出錯(cuò);
? 0:等待超時(shí),沒有可讀寫或錯(cuò)誤的文件。


錯(cuò)誤碼:

執(zhí)行成功則返回文件描述詞狀態(tài)已改變的個(gè)數(shù),如果返回0代表在描述詞狀態(tài)改變前已超過timeout時(shí)間,當(dāng)有錯(cuò)誤發(fā)生時(shí)則返回-1,錯(cuò)誤原因存于errno,此時(shí)參數(shù)readfds,writefds,exceptfds和timeout的值變成不可預(yù)測(cè)。
?

EBADF 文件描述詞為無效的或該文件已關(guān)閉EINTR 此調(diào)用被信號(hào)所中斷EINVAL 參數(shù)n為負(fù)值。ENOMEM 核心內(nèi)存不足

函數(shù)說明:

select()用來等待文件描述詞狀態(tài)的改變。參數(shù)maxfdp代表最大的文件描述詞加1,參數(shù)readfds、writefds和exceptfds 稱為描述詞組,是用來回傳該描述詞的讀,寫或例外的狀況。底下的宏提供了處理這三種描述詞組的方式:

FD_CLR(inr fd,fd_set* set); 用來清除描述詞組set中相關(guān)fd的位FD_ISSET(int fd,fd_set *set); 用來測(cè)試描述詞組set中相關(guān)fd的位是否為真FD_SET(int fd,fd_set*set); 用來設(shè)置描述詞組set中相關(guān)fd的位FD_ZERO(fd_set *set); 用來清除描述詞組set的全部位

結(jié)構(gòu)體說明:

1)struct fd_set可以理解為一個(gè)集合,這個(gè)集合中存放的是文件描述符(filedescriptor),即文件句柄,這可以是我們所說的普通意義的文件,當(dāng)然Unix下任何設(shè)備、管道、FIFO等都是文件形式,全部包括在內(nèi),所以毫無疑問一個(gè)socket就是一個(gè)文件,socket句柄就是一個(gè)文件描述符。
fd_set集合可以通過一些宏由人為來操作,比如
?

清空集合FD_ZERO(fd_set *); 將一個(gè)給定的文件描述符加入集合之中FD_SET(int ,fd_set*); 將一個(gè)給定的文件描述符從集合中刪除FD_CLR(int,fd_set*); 檢查集合中指定的文件描述符是否可以讀寫FD_ISSET(int ,fd_set* )。一會(huì)兒舉例說明。

2)struct timeval是一個(gè)大家常用的結(jié)構(gòu),用來代表時(shí)間值,有兩個(gè)成員,一個(gè)是秒數(shù),另一個(gè)是微妙數(shù)。如下所示:

truct timeval {time_t tv_sec; //seconds 秒time_t tv_usec; //microseconds 微秒,1000000 微秒 = 1秒 }; //頭文件 #include <sys/time.h>

注意:

1.select()函數(shù)里面的各個(gè)文件描述符fd_set集合的參數(shù)在select()前后發(fā)送了變化:

前:表示關(guān)心的文件描述符集合

后:有數(shù)據(jù)的集合(如不是在超時(shí)返回的情況下)

換句話說就是:我們先是設(shè)置了要監(jiān)控的各個(gè)I/O的文件描述符到fd_set集合,然后調(diào)用select(),最后fd_set集合只剩下有"異常"(包括讀、寫、異常)的文件描述符,所以上面說到的這些設(shè)置fd_set集合、調(diào)用select()、判斷是哪些IO有數(shù)據(jù)的步驟通常都是while循環(huán)中實(shí)現(xiàn)。

2.調(diào)用select函數(shù)前后fd_set集合發(fā)送的變化,是由kernel來完成的。

示例1:Linux下監(jiān)控鍵盤上是否有數(shù)據(jù)到來?

#include <sys/time.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <assert.h>#include <unistd.h> #include <iostream> using namespace std;int main () {int keyboard;int ret,i;char c;fd_set readfd;struct timeval timeout;keyboard = open("/dev/tty",O_RDONLY | O_NONBLOCK);assert(keyboard>0);while(1){timeout.tv_sec=1;timeout.tv_usec=0;FD_ZERO(&readfd); //結(jié)構(gòu)體清0FD_SET(keyboard,&readfd); //把鍵盤文件的句柄加入"讀集合"之中///監(jiān)控函數(shù)ret=select(keyboard+1,&readfd,NULL,NULL,&timeout); //第一個(gè)參數(shù)為最大文件句柄+1if(ret == -1) //錯(cuò)誤情況cout<<"error"<<endl ;else if(ret) //返回值大于0 有數(shù)據(jù)到來if(FD_ISSET(keyboard,&readfd)) //檢查集合中鍵盤文件是否可以讀(因?yàn)榧尤?#34;讀集合"的可能不止鍵盤){ /* 讀出鍵盤的數(shù)據(jù) */i=read(keyboard,&c,1);if('\n'==c)continue;printf("hehethe input is %c\n",c);if ('q'==c)break;}else //超時(shí)情況{cout<<"time out"<<endl;continue;}} }

示例2:Linux下監(jiān)控多個(gè)文件是否可讀(偽代碼)?

1. fd_set tRFds; //定義fd_set類型結(jié)構(gòu)體的變量tRFdsFD_ZERO(&tRFds); //結(jié)構(gòu)體先清0int g_iMaxFd = -1; //定義g_iMaxFd記錄 最大句柄+1 2.比較要監(jiān)控的各個(gè)文件的句柄,取出最大值再加1賦給g_iMaxFdif(Fd1 > Fd2){g_iMaxFd = Fd1+1;}else{g_iMaxFd = Fd2+1;} 3.FD_SET(Fd1, &tRFds); //把Fd1、Fd2加入"讀集合"之中FD_SET(Fd2, &tRFds); //Fd1和Fd2為兩個(gè)不同的文件句柄... 4.iRet = select(g_iMaxFd, &tRFds, NULL, NULL, NULL);if (iRet > 0) //返回正數(shù)說明有數(shù)據(jù)可讀了{(lán)if (FD_ISSET(Fd1, &tRFds)) //是文件1可讀{Fd1_read(...);}else if(FD_ISSET(Fd2, &tRFds)) //是文件2可讀{ Fd2_read(...); } ...}

本文主要參考:select函數(shù)的使用_mayue_web的博客-CSDN博客_select函數(shù)用法

總結(jié)

以上是生活随笔為你收集整理的Linux下IO多路复用之select函数的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜影院免费体验区 | 国产精品s | 日韩青青草 | 欧美日韩亚洲一区二区 | 欧美男女激情 | 久久久婷婷 | 亚洲爱爱网 | 一本大道av伊人久久综合 | 亚洲视频999 | 日韩欧美国产网站 | 韩日视频在线 | 极度诱惑香港电影完整 | 日本一区中文字幕 | 三级欧美韩日大片在线看 | 亚洲视频精品在线 | 男人把女人捅爽 | 精品香蕉99久久久久网站 | 四虎精品永久在线 | 天天操操操 | 亚洲色图日韩 | 91偷拍视频 | 国产精品一区二区免费在线观看 | 免费在线毛片 | 国产精品乱码久久久久久久久 | 中文有码一区 | 成人一级影片 | 精品动漫一区二区 | 在线观看免费高清视频 | 天天摸天天爽 | 国产一区二区黑人欧美xxxx | 日本午夜精品理论片a级app发布 | 一区二区精品视频 | 波多野结衣在线电影 | 99午夜视频| 日本少妇videos高潮 | 3d动漫啪啪精品一区二区中文字幕 | 国产成人99久久亚洲综合精品 | 天天色天天操天天 | 国产成人亚洲精品自产在线 | 日韩一区在线观看视频 | 激情午夜av | 国产福利在线观看视频 | av永久免费在线观看 | 日韩日b视频 | 国产高清毛片 | 免费日韩欧美 | 99热亚洲| 日本妇女毛茸茸 | 2018天天操 | 亚洲av无码专区国产乱码不卡 | 日韩三级一区二区三区 | 免费精品视频一区二区三区 | 91黑丝在线观看 | av导航在线观看 | 国产精品无码中文 | 99成人在线视频 | 日日天天干| 视频毛片| 欧美日韩精品一区 | 天天操天天干天天爽 | 人人妻人人玩人人澡人人爽 | 日韩福利视频导航 | 华人av在线| 最新在线观看av | 国产极品网站 | 欧美久久精品一级黑人c片 1000部多毛熟女毛茸茸 | 99青青草 | 性视频欧美 | 天天插天天射天天干 | 精品一级 | 99热在线免费观看 | 日韩亚洲欧美中文字幕 | 国产女厕一区二区三区在线视 | 久久国产人妻一区二区免色戒电影 | 伊人66 | 大片视频免费观看视频 | 欧美性插动态图 | 亚洲色成人www永久在线观看 | 国产精品美乳在线观看 | 日本加勒比中文字幕 | 日韩精品小视频 | 国产精品自产拍高潮在线观看 | 国产日韩欧美精品 | 男女超爽视频免费播放 | 欧美国产精品一二三 | 成人久久久精品国产乱码一区二区 | 日韩免费淫片 | 天天操天天爽天天射 | 欧美精品一区二区久久婷婷 | 狠狠干狠狠干狠狠干 | 日日日日日日 | 亚洲一区二区三区中文字幕 | 在线免费观看污网站 | av大全网站 | 欧美区二区三区 | 国产无遮挡18禁无码网站不卡 | 亚洲一区二区视频在线 | 欧美人伦| 日韩欧美国产一区二区 |