epoll模型

1. 主要函数
   a. epoll_create(int size)
       a) 创建epoll句柄,size告诉内核监听数目的大小
       b) 返回一个epoll专用的文件描述符
   b. epoll_ctl(int epfd,int op,int fd,struct epoll_event* event)
       a) 控制某个epoll文件描述符上的事件,可以注册事件,修改事件,删除事件
       b) 第一个参数是epoll_create返回值,第二个参数表示动作,第三个参数是需要监听的fd,第四个参数是告诉内核需要监听什么事件
       c)  EPOLL_CTL_ADD 注册新的fd到epfd
           EPOLL_CTL_MOD 修改已经注册的fd的监听事件
           EPOLL_CTL_DEL 从epfd中删除一个fd
       d) EPOLLIN  表示对应的文件描述符可以读
           EPOLLOUT 表示对应的文件描述符可以写
           EPOLLPRI 表示对应的文件描述符有紧急数据可读
           EPOLLERR 表示对应的文件描述符发生错误
           EPOLLHUP 表示对应的文件描述符被打断
           EPOLLET  将epoll设置为边缘触发,表示对应的文件描述符有事件发生
           EPOLLONESHOT  只监听一次事件,当监听完这次事件后,如果还需继续监听这个socket,则需再次把这个socket加入到epoll对列
     e) 返回0代表成功,1代表失败
   c. epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout)
       a) 检测事件发生
       b) events是从内核得到事件的集合,maxevents告诉内核这个events大小,timeout是超时时间
       c) 函数返回需要处理的事件数目,返回0表示超时,-1表示阻塞

2. 使用流程 

       a) 使用epoll_create()函数创建文件描述,设定将可管理的最大socket描述符数目。
       b) 创建与epoll关联的接收线程,应用程序可以创建多个接收线程来处理epoll上的读通知事件,线程的数量依赖于程序的具体需要。
       c) 创建一个侦听socket描述符ListenSock;将该描述符设定为非阻塞模式,调用Listen()函数在套接字上侦听有无新的连接请求,在 epoll_event结构中设置要处理的事件类型EPOLLIN,工作方式为 epoll_ET,以提高工作效率,同时使用epoll_ctl()注册事件,最后启动网络监视线程。
       d) 网络监视线程启动循环,epoll_wait()等待epoll事件发生。
       e) 如果epoll事件表明有新的连接请求,则调用accept()函数,将用户socket描述符添加到epoll_data联合体,同时设定该描述符为非 阻塞,并在epoll_event结构中设置要处理的事件类型为读和写,工作方式为epoll_ET.
       f) 如果epoll事件表明socket描述符上有数据可读,则将该socket描述符加入可读队列,通知接收线程读入数据,并将接收到的数据放入到接收数据 的链表中,经逻辑处理后,将反馈的数据包放入到发送数据链表中,等待由发送线程发送。

3. 工作模式
    a. Edge Triggered  高速工作方式,只支持no-block socket 当io事件发生时内核通知你后不会再通知你,一直到你执行的操作导致那个文件描述符事件改变,如果
                               你不对其进程io操作,内核不会再通知你,write和read操作必须一直处理到出错(errno==EAGAIN),才能进行下一个操作,epoll工作在ET模式 的时候,必须使用非阻塞套接口,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死

    b. Level Triggered 缺省的工作方式,支持block和no-block socket,内核告诉你一个文件描述符是否就绪,然后你就可以对这个就绪的fd进行io操作,只要还有没有
                              处理的事件,内核就会一直通知你

4. 优点

   a 支持一个进程打开最大数目的socket描述符(FD)

   b io效率不随FD增加而线性下降

   c 使用mmp加速内核与用户空间消息传递

   d 内核微调

5. Epoll 数据结构

   struct epoll_event {
       __uint32_t events;      // Epoll events
       epoll_data_t data;      // User data variable
   };

  typedef union epoll_data {
       void *ptr;
       int fd;
       __uint32_t u32;
       __uint64_t u64;
  } epoll_data_t;

 

posted on 2012-10-10 14:04  kangbry  阅读(367)  评论(0编辑  收藏  举报

导航