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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux:I/O多路转接之select(有图有代码有真相!!!)

發布時間:2023/12/20 linux 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux:I/O多路转接之select(有图有代码有真相!!!) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、select引入

一次 I/O 分為兩個部分:1)等待數據就緒 ? ? ?2)進行數據轉移

1、select 原理:

select的原理就是減少等待數據就緒的比重,巧妙的利用等待隊列機制讓用戶進程適當在沒有資源可讀/寫時睡眠,有資源可讀/寫時喚醒。下面我們看

看select睡眠的詳細過程。 ?

select會循環遍歷它所監測的fd_set(一組文件描述符(fd)的集合)內的所有文件描述符對應的驅動程序的poll函數。驅動程序提供的poll函數首先會將

調用select的用戶進程插入到該設備驅動對應資源的等待隊列(如讀/寫等待隊列),然后返回一個bitmask告訴select當前資源哪些可用。當select循環遍歷完

所有fd_set內指定的文件描述符對應的poll函數后,如果沒有一個資源可用(即沒有一個文件可供操作),則select讓該進程睡眠,一直等到有資源可用為止,

進程被喚醒(或者timeout)繼續往下執行。



select:系統提供select函數來實現多路復用輸入/輸出模型。select系統調用是?用來讓我們的程序監視多個文件句柄的狀態變化的。?

程序會停在select這里等待,直到被監視的文件句柄有一個或多個發生了狀態改變。?

句柄:?0是標準輸?入,1是標準輸出,2是標準錯誤輸出。0、1、2是整數表?示的,對應的FILE *?結構的表?示就是stdin、stdout、stderr。

2、select 參數


nfds:是需要監視的最大的?文件描述符值+1;

rdset:需要檢測的可讀?文件描述符的集合

wrset:可寫?文件描述符的集合

exset:常?文件描述符的集合。

struct timeval結構?用于描述?一段時間長度,如果在這個時間內,需要監視的描述符沒有事件發生則函數返回,返回值為0。


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

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

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

FD_SET(int fd,fd_set*set);?用來設置描述詞組set中相關fd的位

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

參數timeout為結構timeval,?用來設置select()的等待時間,其結構定義如下:




如果參數timeout設為:

NULL:則表示select()沒有timeout,select將?一直被阻塞,直到某個文件描述符上發生了事件。
0:僅檢測描述符集合的狀態,然后立即返回,并不等待外部事件的發?生。
特定的時間值:如果在指定的時間段里沒有事件發生,select將超時返回。


函數返回值:

執行成功則返回?文件描述詞狀態已改變的個數

如果返回0代表在描述詞狀態改變前已超過timeout時間,沒有返回;

當有錯誤發?生時則返回-1,錯誤原因存于errno,此時參數readfds,writefds,exceptfds和

timeout的值變成不可預測。錯誤值可能為:

EBADF 文件描述詞為無效的或該文件已關閉

EINTR 此調?用被信號所中斷

EINVAL 參數n 為負值。

ENOMEM 核心內存不足


3、select模型的特點:?
1)、可監控的?文件描述符個數取決與sizeof(fd_set)的值。我這邊服務 器上sizeof(fd_set)=512,每bit表?示一個?文件描述符,則我服務器上?支持的最大文件描述符是512*8=4096。? 2)、將fd加入select監控集的同時,還要再使用一個數據結構array保存放到select監控集中的fd,一是用于再select 返回后,array作為源數據和fd_set進行FD_ISSET判斷。二是select返回后會把以前加入的但并無事件發生的fd清空,則每次開始 select前都要重新從array取得fd逐一加入(FD_ZERO最先),掃描array的同時取得fd最大值maxfd,用于select的第一個 參數。? ? ? ? ? ? ? ? 3)、select模型必須在select前循環array(加fd,取maxfd),select返回后循環array(FD_ISSET判斷是否有時間發生)。
4、select缺點:?
(1)每次調用select,都需要把fd集合從用戶態拷貝到內核態,這個開銷在fd很多時會很大? (2)同時每次調用select都需要在內核遍歷傳遞進來的所有fd,這個開銷在fd很多時也很大?

(3)select支持的文件描述符數量太小了,默認是1024


5、select 服務器

#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<sys/select.h> #include<arpa/inet.h> #include<netinet/in.h> #include<string.h> int array_fds[1024]; static void usage(char *proc) {printf("usage:%s [local_ip] [local_port]\n",proc); } int startup(char* _ip,int _port) {//create socketint sock=socket(AF_INET,SOCK_STREAM,0);if(sock<0){perror("socket");return 2;}//port multiplexingint flg=1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&flg,sizeof(flg));struct sockaddr_in local;local.sin_family=AF_INET;local.sin_addr.s_addr=inet_addr(_ip);local.sin_port=htons(_port);//bindif(bind(sock,(struct sockaddr*)&local,sizeof(local))<0){perror("bind");return 3;}//listenif(listen(sock,10)<0){perror("listen");return 4;}return sock; } int main(int argc,char *argv[]) {if(argc!=3){usage(argv[0]);return 1;}int listen_sock=startup(argv[1],atoi(argv[2]));int maxfd=0;fd_set rfds;int array_size=sizeof(array_fds)/sizeof(array_fds[0]);array_fds[0]=listen_sock;int i=1;for(;i<array_size;i++){array_fds[i]=-1;}while(1){struct timeval _timeout={0,0};FD_ZERO(&rfds);maxfd=-1;for(i=0;i<array_size;i++){if(array_fds[i]>0){FD_SET(array_fds[i],&rfds);if(array_fds[i]>maxfd){maxfd=array_fds[i];}}}switch(select(maxfd+1,&rfds,NULL,NULL,&_timeout)){case 0:printf("timeout...\n");break;case -1:perror("select\n");break;default:{int j=0;for(;j<array_size;j++){if(array_fds[j]<0){continue;}if(j==0 && FD_ISSET(array_fds[j],&rfds)){struct sockaddr_in client;socklen_t len=sizeof(client);int new_fd=accept(array_fds[j],\(struct sockaddr*)&client,&len);if(new_fd<0){perror("accept");continue;}else{printf("get a new client:(%s %d)\n",\inet_ntoa(client.sin_addr),\ntohs(client.sin_port));int k=1;for(;k<array_size;k++){if(array_fds[k]<0){array_fds[k]=new_fd;break;}}if(k==array_size){close(new_fd);}}}else if(j!=0 && FD_ISSET(array_fds[j],&rfds)){char buf[10240];ssize_t s=read(array_fds[j],buf,sizeof(buf)-1);if(s>0){buf[s]=0;printf("client say:%s\n",buf);}else if(s==0){printf("client quit\n");close(array_fds[j]);array_fds[j]=-1;}else{perror("read");close(array_fds[j]);array_fds[j]=-1;}}}}break;}}return 0; }

總結

以上是生活随笔為你收集整理的Linux:I/O多路转接之select(有图有代码有真相!!!)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 北条麻妃av在线 | 伊人久久久久噜噜噜亚洲熟女综合 | 在线观看高清视频 | 国产大片一区二区三区 | 桃色一区| 88国产精品视频一区二区三区 | 激情国产视频 | 免费成人黄 | 奶水旺盛的少妇在线播放 | 亚洲国产精品久久久久爰色欲 | 日韩中文字幕免费观看 | 日日夜夜撸撸 | 国产精品30p | 黄色一级视频免费 | 99视频在线观看视频 | 亚洲欧美国产高清 | 欧洲色av| 巨胸大乳www视频免费观看 | 婷婷久久丁香 | 91色| 亚洲高清视频一区二区 | 在线观看日韩国产 | 精品无码三级在线观看视频 | 农村老熟妇乱子伦视频 | 美女扒开内裤让男人捅 | 免费爱爱视频 | 久久伊人影视 | 国产视频一区二区三区四区五区 | 国产色播 | 国产宾馆实践打屁股91 | 99热6这里只有精品 三级av在线免费观看 | 中文字幕在线播放视频 | 在线观看亚洲欧美 | 黄色a毛片| 久久资源365 | www.av麻豆 | 18+视频在线观看 | 亚洲伦理在线视频 | 亚洲国产中文字幕在线观看 | 日韩一级在线观看 | 深夜成人福利 | 精品久久毛片 | 美女脱了裤子让男人桶 | 直接看av的网站 | 一级全黄裸体免费视频 | 欧美激情精品久久久久久变态 | 欧美一级做 | 中文精品久久久久人妻不卡 | 国产精品扒开腿做爽爽爽a片唱戏 | 毛片在线网 | 国产资源在线免费观看 | 麻豆精品免费观看 | 中出一区二区 | 国产成人a亚洲精品 | 亚洲欧美另类在线视频 | 雪白的扔子视频大全在线观看 | 少妇诱惑av | www,xxx日本| 红桃视频国产精品 | 少妇做爰免费视频播放 | 人人爽在线 | 免费在线你懂的 | www.日韩欧美 | 国产亚洲天堂 | 久久精品99国产精品日本 | 日本a视频 | 精品一区三区 | 色亚洲色图 | 国产午夜久久 | 2019国产在线 | 完全免费在线视频 | 老妇裸体性激交老太视频 | 日韩影视一区 | 激情六月丁香 | www夜片内射视频日韩精品成人 | 免费一级特黄3大片视频 | 天天插日日插 | 国产一区亚洲二区三区 | 欧美日韩中文一区 | 日本青青草| 性爱免费视频 | 人民的名义第二部 | 男同志毛片特黄毛片 | 国产午夜电影在线观看 | 日韩精品欧美在线 | 国产午夜无码视频在线观看 | 三级av毛片| 日日摸夜夜添夜夜添高潮喷水 | 免费国产黄 | a级黄色在线观看 | 婷婷激情网站 | 亚洲涩涩图 | 国产欧美精品一区 | 青草精品视频 | 小泽玛丽亚在线观看 | 欧美极品少妇xxxxⅹ裸体艺术 | 欧美激情国产精品免费 | 少妇一级淫免费观看 | 九色91av |