欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

IO复用模型epoll

程序员文章站 2022-06-13 12:38:36
...

一、简介

epoll是Linux多路复用IO接口select/poll的加强版,e对应的英文单词就是enhancement【增强】

定义:epoll是一种当文件描述符的内核缓冲区非空的时候,发出可读信号进行通知,当写缓冲区不满的时候,发出可写信号通知的机制

二、方法

  • epoll_create :创建epoll实例,会创建所需要的红黑树,以及就绪链表,以及代表epoll实例的文件句柄

  • epoll_ctl:添加,修改,或者删除 注册到epoll实例中的文件描述符上的监控事件

  • epoll_wait:等待epoll实例中注册的事件触发

三、流程

1、进程调用epoll_create方法时,Linux内核会创建一个eventpoll结构体。

struct eventpoll{
    ....
    /*红黑树的根节点【红黑树数据结构,操作时间复杂度lgn】,这颗树中存储着所有添加到epoll中的需要监控的事件*/
    struct rb_root  rbr;
    /*双链表中则存放着将要通过epoll_wait返回给用户的满足条件的事件*/
    struct list_head rdlist;
    ....
};

2、进程调用epoll_ctl方法,向epoll对象中添加事件对象,这些事件对象会存储在rbr红黑树上,所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系,也就是说,当相应的事件发生时会调用这个回调方法。这个回调方法在内核中叫ep_poll_callback,它会将发生的事件添加到rdlist双链表中。

事件对象—epitem结构体

struct epitem{
    struct rb_node  rbn;//红黑树节点
    struct list_head    rdllink;//双向链表节点
    struct epoll_filefd  ffd;  //事件句柄信息
    struct eventpoll *ep;    //指向其所属的eventpoll对象
    struct epoll_event event; //期待发生的事件类型
}

3、调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可。如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户。

IO复用模型epoll

三部曲:

第一步:epoll_create()系统调用。此调用返回一个句柄,之后所有的使用都依靠这个句柄来标识。

第二步:epoll_ctl()系统调用。通过此调用向epoll对象中添加、删除、修改感兴趣的事件,返回0标识成功,返回-1表示失败。

第三部:epoll_wait()系统调用。通过此调用收集收集在epoll监控中已经发生的事件。

四、工作模式

水平触发(level-trggered) :
只要文件描述符关联的读内核缓冲区非空,有数据可以读取,就一直发出可读信号进行通知,
当文件描述符关联的内核写缓冲区不满,有空间可以写入,就一直发出可写信号进行通知

边缘触发(edge-triggered) :
当文件描述符关联的读内核缓冲区由空转化为非空的时候,则发出可读信号进行通知,
当文件描述符关联的内核写缓冲区由满转化为不满的时候,则发出可写信号进行通