zoukankan      html  css  js  c++  java
  • IO复用之epoll

    epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率.

    epoll类似于事件机制,有客户端数据发送过来了,就激活了事件,所以极大的提高了效率,适用于高并发的服务端的开发.

    epoll也有一般的形式:

     1   int epofd = 0;                                                      //epoll对象
     2     int fds = 0;                                                            //活跃连接对象
     3     int i = 0;
     4     int er = 0;
     5     int sock_fd = 0;
     6     int len = 0;
     7 
     8     struct epoll_event event;                                   //epoll事件
     9     struct epoll_event events[MAX_NUM];
    10 
    11     struct sockaddr_in client;
    12 
    13     len = sizeof(struct sockaddr_in);
    14 
    15     epofd =    epoll_create(MAX_NUM);                                //创建epoll对象
    16     if(epofd < 0){
    17         perror("epoll创建失败");
    18         return -1;
    19     }
    20 
    21     fcntl(listen_fd,F_SETFL,O_NONBLOCK);                        //将监听套接字转化为非堵塞的监听套接字
    22 
    23     event.data.fd = listen_fd;                                              //设置epoll事件
    24     event.events = EPOLLIN;
    25 
    26     er = epoll_ctl(epofd,EPOLL_CTL_ADD,listen_fd,&event);       //添加epoll事件
    27     if(er < 0){
    28         perror("epoll_ctl出错");
    29         return -1;
    30     }
    31 
    32     while(1){
    33         fds = epoll_wait(epofd,events,MAX_NUM,-1);              //等待数据连接
    34         if(fds < 0){
    35             perror("epoll_wait出错");
    36             continue;
    37         }
    38 
    39         for(i = 0;i < fds;i++){
    40             if(events[i].data.fd == listen_fd){                                                                 //判断是否是新联接
    41                 sock_fd = accept(listen_fd,(struct sockaddr *)&client,&len);                //接受连接
    42                 if(sock_fd < 0){
    43                     perror("有客户端连接失败");
    44                     continue;
    45                 }
    46 
    47                 //将连接添加到事件中
    48                 event.data.fd = sock_fd;
    49                 event.events = EPOLLIN | EPOLLET;
    50                 epoll_ctl(epofd,EPOLL_CTL_ADD,sock_fd,&event);
    51 
    52                 printf("有新连接%d
    ",sock_fd);
    53 
    54                 continue;
    55             }else {
    56                 er = rev_data(events[i].data.fd);//新的数据发送过来了
    57                 if(er == 0){//客户端断开连接
    58                     epoll_ctl(epofd,EPOLL_CTL_DEL,events[i].data.fd,&event);//取消该客户端的时间监听
    59                     close(events[i].data.fd);//关闭套接字
    60                     continue;
    61                 }
    62             }
    63 
    64         }
    65 
    66     }
  • 相关阅读:
    重载函规则
    lambd
    内联函数
    c和c++中的枚举和 区别
    关于于c++中的类型转换
    作用域解析运算符
    day01
    二级指针输入特性
    二级指针的 数出特性
    influence maximization 第二弹
  • 原文地址:https://www.cnblogs.com/CHYI1/p/5496224.html
Copyright © 2011-2022 走看看