您的位置:首页 > 技术中心 > 运维 >

I/O多路复用中select指的是什么

时间:2023-05-14 00:34

select是用于监视多个文件描述符状态的变化的。即用来监视文件描述符读/写/异常状态是否就绪。

函数原型:int select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);

select的几大缺点:

(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大

(3)select支持的文件描述符数量太小了

  1 #include<stdio.h>  2 #include<string.h>  3 #include<stdlib.h>  4 #include<unistd.h>  5 #include<sys/select.h>  6   7 int main()  8 {  9     int std_in = 0; 10 //  int std_out = 1; 11     fd_set reads; 12 //  fd_set writes; 13     //int max_nums = std_out; 14     int max_nums = std_in; 15     FD_ZERO(&reads); 16 //  FD_ZERO(&writes); 17     FD_SET(std_in,&reads); 18 //  FD_SET(std_out,&writes); 19     struct timeval _timeout = {5,0}; 20     int done = 0; 21     while(!done) 22     { 23         _timeout.tv_sec = 5;  24         _timeout.tv_usec = 0; 25         //switch(select(max_nums+1,&reads,&writes,NULL,&_timeout)) 26         switch(select(max_nums+1,&reads,NULL,NULL,&_timeout)) 27         { 28             case -1: 29                 perror("select"); 30                 break; 31             case 0: 32                 printf("timeout...
"); 33                 break; 34             default://success 35                 { 36                     if(FD_ISSET(std_in,&reads)) 37                     {//read 38                         char buf[1024]; 39                         memset(buf,'',sizeof(buf)); 40                         ssize_t size = read(std_in,buf,sizeof(buf)-1); 41                         if(size<0) 42                         { 43                             perror("read"); 44                             exit(1); 45                         } 46                         if(strncmp(buf,"quit",4)==0)  47                         { 48                             done =1; 49                             continue; 50                         } 51                         printf("echo: %s",buf); 52  53                     } 54                 //  if(FD_ISSET(std_out,&writes)) 55                 //  {//writes 56                 //      char buf[1024]; 57                 //      while(1) 58                 //      { 59                 //          memset(buf,'',sizeof(buf)); 60                 //          strcpy(buf,"hello world"); 61                             //write(1,buf,sizeof(buf)-1); 62                 //          printf("%s
",buf); 63                 //      } 64                 //  } 65                     break; 66                 } 67         } 68     } 69     return 0; 70 } [fbl@localhost select]$ ./select helloecho: hellohiecho: hinihaoecho: nihaoahhauecho: ahhauquit[fbl@localhost select]$
  1 #include<stdio.h>  2 #include<string.h>  3 #include<stdlib.h>  4 #include<unistd.h>  5 #include<sys/socket.h>  6 #include<sys/select.h>  7 #include<sys/types.h>  8 #include<netinet/in.h>  9 #include<arpa/inet.h> 10 #include<assert.h> 11  12 #define _BACKLOG_ 5 13 int fd[64]; 14 void usage(char *_port) 15 { 16     printf("%s,[ip],[port]
",_port); 17 } 18 int startup(char *ip,int port) 19 { 20     assert(ip); 21     int sock = socket(AF_INET,SOCK_STREAM,0); 22     if(sock<0) 23     { 24         perror("socket"); 25         exit(1); 26     } 27     struct sockaddr_in local; 28     local.sin_family = AF_INET; 29     local.sin_port = htons(port); 30     local.sin_addr.s_addr = inet_addr(ip); 31     if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) 32     { 33         perror("bind"); 34         exit(2); 35     } 36     if(listen(sock,_BACKLOG_)<0) 37     { 38         perror("listen"); 39         exit(3); 40     } 41     return sock; 42  43  44 } 45 int main(int argc,char *argv[]) 46 { 47     if(argc!=3) 48     { 49         usage(argv[0]); 50         return 1; 51     } 52     int port = atoi(argv[2]); 53     char *ip = argv[1]; 54     int listen_sock = startup(ip,port); 55     int new_sock = -1; 56     struct sockaddr_in client; 57     socklen_t len = sizeof(client); 58     fd_set reads; 59     fd_set writes; 60     int max_nums; 61     struct timeval _timeout = {5,0}; 62     int done = 0; 63     int i =0; 64     int fd_nums = sizeof(fd)/sizeof(fd[0]); 65     for(;i<fd_nums;++i) 66     { 67         fd[i]=-1; 68     } 69     fd[0] = listen_sock;  70     while(!done) 71     { 72         _timeout.tv_sec = 5; 73         _timeout.tv_usec = 0; 74         FD_ZERO(&reads); 75         FD_ZERO(&writes); 76         for(i=0;i<fd_nums;++i) 77         { 78             if(fd[i]>0) 79             { 80                 FD_SET(fd[i],&reads); 81                 if(fd[i]>max_nums) 82                 { 83                     max_nums = fd[i]; 84                 } 85  86             } 87         } 88         switch(select(max_nums+1,&reads,&writes,NULL,&_timeout)) 89         { 90             case -1: 91                 perror("select"); 92                 break; 93             case 0: 94                 printf("timeout...
"); 95                 break; 96             default: 97                 { 98  99                     for(i=0;i<fd_nums;++i)100                     {101                         if(fd[i]==listen_sock && FD_ISSET(fd[i],&reads))102                         {103                             new_sock = accept(listen_sock,(struct sockaddr*)    &client,&len);104                             if(new_sock<0)105                             {106                                 perror("accept");107                                 continue;108                             }109                             for(i=0;i<fd_nums;++i)110                             {111                                 if(fd[i]==-1)112                                 {113                                     fd[i]=new_sock;114                                 }115                             }116 117                         }118                         else if(fd[i]>0 && FD_ISSET(fd[i],&reads))119                         {120                             char buf[1024];121                             memset(buf,'',sizeof(buf));122                             ssize_t size = read(new_sock,buf,sizeof(buf)-1);123                             if(size<0)124                             {125                                 perror("read");126                                 exit(4);127                             }128                             else if(size==0)129                             {130                                 printf("client close...
");131                                 close(fd[i]);132                                 fd[i]=-1;133                             }134                             else135                             {136                                 buf[size]='';137                             }138                             printf("client:%s
",buf);139                         }140                         else141                         {}142                     }143 144                     break;145                 }146 147         }148     }149     return 0;150 }1 #include<stdio.h>  2 #include<string.h>  3 #include<stdlib.h>  4 #include<unistd.h>  5 #include<sys/socket.h>  6 #include<sys/select.h>  7 #include<sys/types.h>  8 #include<netinet/in.h>  9 #include<arpa/inet.h> 10 void usage(char *_port) 11 { 12     printf("%s,[ip],[port]
",_port); 13 } 14 int main(int argc,char *argv[]) 15 { 16     if(argc!=3) 17     { 18         usage(argv[0]); 19         return 1; 20     } 21     int port = atoi(argv[2]); 22     char *ip = argv[1]; 23     int sock = socket(AF_INET,SOCK_STREAM,0); 24     if(sock<0) 25     { 26         perror("socket"); 27         exit(1); 28     } 29     struct sockaddr_in remote; 30     remote.sin_family = AF_INET; 31     remote.sin_port = htons(port); 32     remote.sin_addr.s_addr = inet_addr(ip); 33     int ret = connect(sock,(struct sockaddr*)&remote,sizeof(remote)); 34     if(ret<0) 35     { 36         perror("connect"); 37         exit(1); 38     } 39     char buf[1024]; 40     while(1) 41     { 42  43         memset(buf,'',sizeof(buf)); 44         printf("please say:"); 45         scanf("%s",buf); 46         ssize_t size = write(sock,buf,sizeof(buf)-1);  47         if(size<0) 48         { 49             perror("write"); 50             exit(2); 51         } 52         else if(size ==0) 53         {} 54         else 55         { 56             printf("client : %s
",buf); 57         } 58     } 59     return 0; 60 }[fbl@localhost select_socket]$ ./server 192.168.1.106 8080timeout...client:helloclient:hiclient:huowoclient close...client:read: Bad file descriptor[fbl@localhost select_socket]$ [fbl@localhost select_socket]$ ./client 192.168.1.106 8080please say:helloclient : helloplease say:hiclient : hiplease say:huowoclient : huowoplease say:^C[fbl@localhost select_socket]$

以上就是I/O多路复用中select指的是什么的详细内容,更多请关注Gxl网其它相关文章!

热门排行

今日推荐

热门手游