select服务器

                   多进程和多线程服务器有什么缺点呢?

多进程服务器缺点:

    1.内存消耗比较大,每个进程都独立加载完整的应用环境

      2.cpu消耗偏高,高并发下,进程之间频繁进行上下文切换,需要大量的内存换页操作

      3.很低的io并发处理能力,只适合处理短请求,不适合处理长请求

多线程服务器缺点:

    1.不方便操作系统的管理

    2.VM对内存的管理要求非常高,GC的策略会影响多线程并发能力和系统吞吐量

    3.由于存在对共享资源操作,一旦出现线程"死锁"和线程阻塞,很容易使整个应用失去可用性


用他们编写的服务器,当用户增多时,服务器性能也会下降


为了解决这个问题,select就出现了。

select服务器的优点:

1. 高性能 (与多进程和多线程比较)
(1)select一次等待多个文件描述符;
(2)select的cpu压力低;
(3)等待时间变短,提升了性能;

  select服务器的缺点:

(1)每次调⽤用select,都需要把fd集合从⽤用户态拷贝到内核态,这个开销在fd很多时会很⼤大
(2)同时每次调⽤用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很⼤大
(3)select⽀支持的⽂文件描述符数量太⼩小了,默认是1024



select服务器代码如下

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          #include 
         
           int array_fds[1024]; int startup(char * _ip, int _port) { int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { perror("create socket is fail"); return 2; } struct sockaddr_in peer; peer.sin_family = AF_INET; peer.sin_port = htons(_port); peer.sin_addr.s_addr = inet_addr(_ip); int opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if(bind(sock, (struct sockaddr*)&peer, sizeof(peer)) < 0) { perror("bind"); return 3; } if(listen(sock, 10) < 0) { perror("listen"); return 4; } return sock; } static void Usage(const char* proc) { printf("%s[ip][port]\n", proc); } int main(int argc, char *argv[]) { if(argc != 3) { Usage(argv[0]); return 1; } int listensock = startup(argv[1], atoi(argv[2])); int maxfd = 0; int array_size = sizeof(array_fds)/sizeof(array_fds[0]); fd_set rfds; array_fds[0] = listensock; int i = 1; for(; i < array_size; i++) { array_fds[i] = -1; } while(1) { struct timeval _timeout = {5, 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...."); break; case -1: perror("select"); 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("new_fd:accept"); continue; }else { //printf("get a new client:(%s:%d)"); 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[1024]; 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 is quit!"); close(array_fds[j]); array_fds[j] = -1; }else { perror("read"); close(array_fds); array_fds[j] = -1; } } } } break; } } return 0; } 
          
         
       
      
      
     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值