• epoll 使用小结


    了解一下

    Epoll 是一种高效的管理socket的模型,相对于select和poll更加高效。

    数据结构

    • sys/epoll.h
    typedef union epoll_data {
                    void ptr;
                    int fd;
                    __uint32_t u32;
                    __uint64_t u64;
          } epoll_data_t;
    
          struct epoll_event {
                    __uint32_t events;    / Epoll events /
                    epoll_data_t data;    / User data variable /
          };
    

    (1) epoll_data 联合体用来保存触发事件的某个文件描述符相关的数据.
    (2) epoll_event 结构体的events字段是表示感兴趣的事件和被触发的事件:

    EPOLLIN :表示对应的文件描述符可以读;
    EPOLLOUT:表示对应的文件描述符可以写;
    EPOLLPRI:表示对应的文件描述符有紧急的数据可读
    EPOLLERR:表示对应的文件描述符发生错误;
    EPOLLHUP:表示对应的文件描述符被挂断;
    EPOLLET:表示对应的文件描述符设定为edge模式
    

    函数

    *epoll_create, epoll_create1 函数
    函数声明:int epoll_create(int size)
    该函数生成一个epoll专用的文件描述符,其中的参数是指定生成描述符的最大范围。

    • epoll_ctl函数

    函数声明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event event) 该函数用于控制某个文件描述符上的事件,可以注册事件,修改事件,删除事件。
    参数:epfd:由 epoll_create 生成的epoll专用的文件描述符;
    op:要进行的操作例如注册事件:

    EPOLL_CTL_ADD 注册、
    EPOLL_CTL_MOD 修改、
    EPOLL_CTL_DEL 删除
    
    
    • epoll_wait函数
      函数声明: int epoll_wait(int epfd,struct epoll_event events,int maxevents,int timeout) 该函数用于轮询I/O事件的发生;
      参数:
      epfd: 由epoll_create 生成的epoll专用的文件描述符;
      epoll_event: 用于回传代处理事件的数组;
      maxevents: 每次能处理的事件数;
      timeout: 等待I/O事件发生的超时值(ms);-1永不超时,直到有事件产生才触发,0立即返回。返回发生事件数。-1有错误。

    Sample:

    int main()
    {
        //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
        struct epoll_event ev,events[20];
    
        epfd=epoll_create(10000); //创建epoll句柄
       
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        //把socket设置为非阻塞方式
        setnonblocking(listenfd);
       
        bzero(&serveraddr, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = INADDR_ANY;
        serveraddr.sin_port=htons(SERV_PORT);
        bind(listenfd,(struct sockaddr )&serveraddr, sizeof(serveraddr));
        listen(listenfd, 255);
    
        //设置与要处理的事件相关的文件描述符
        ev.data.fd=listenfd;
        //设置要处理的事件类型
        ev.events=EPOLLIN;
        //注册epoll事件
        epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);
    
        for ( ; ; )
        {
          //等待epoll事件的发生
          nfds=epoll_wait(epfd,events,20,1000);
          //处理所发生的所有事件
          for(i=0;i<nfds;++i)
          {
             if(events .data.fd==listenfd)
             {
                    connfd = accept(listenfd,(struct sockaddr )&clientaddr, &clilen);
                    if(connfd<0)
                    {
                      perror("connfd<0");
                    }
                    setnonblocking(connfd);
                    //设置用于读操作的文件描述符
                    ev.data.fd=connfd;
                    //设置用于注测的读操作事件
                    ev.events=EPOLLIN|EPOLLET;
                    //注册event
                    epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
             }
             else if(events .events&EPOLLIN)
             {
                    read_socket(events .data.fd);
                    ev.data.fd=events .data.fd;
                    ev.events=EPOLLIN|EPOLLOUT|EPOLLET;
                    epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
             }
             else if(events .events&EPOLLOUT)
             {
                    write_socket(events .data.fd);
                    ev.data.fd=events .data.fd;
                    ev.events=EPOLLIN|EPOLLET; //ET模式
                epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
             }
             else
             {
                    perror("other event");
             }
          }
        }
    }
    
  • 相关阅读:
    Linux磁盘系统——管理磁盘的命令
    Linux磁盘系统——磁盘系统简介
    LinuxShell——内嵌命令
    安装PHP出现make: *** [sapi/cli/php] Error 1 解决办法
    Linux常用命令
    Linux文件系统及文件类型
    MySQL查询语句
    Python随手记—各种方法的使用
    MySQL架构及SQL语句
    Python笔记记录
  • 原文地址:https://www.cnblogs.com/ikaka/p/4858508.html
Copyright © 2020-2023  润新知