epoll

1、概念

epoll是一种I/O事件通知机制,是Linux内核实现多路复用的一个实现。
epoll是select和poll的增强版本

2、epoll API

epoll核心是三个API
使用的数据结构是红黑树和链表
三个API分别为:

#include <sys/epoll.h>
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

2.1、epoll_create()

int epoll_create(int size)
功能:内核产生一个epoll实例数据结构返回一个文件描述符,这个描述符就是epoll实例的句柄,后面两个接口都是以它为中心(即epfd形参)
size表示要监视文件描述符的最大值。

2.2、epoll_ctl()

epoll事件的注册函数

int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event)
功能:将被监听的描述符添加到红黑树或者从红黑树删除  或者对监听事件进行修改

相关数据结构定义

typedef union epoll_data {
    void *ptr; /* 指向用户自定义数据 */
    int fd; /* 注册的文件描述符 */
    uint32_t u32; /* 32-bit integer */
    uint64_t u64; /* 64-bit integer */
} epoll_data_t;

struct epoll_event {
    uint32_t events; /* 描述epoll事件   events 是** epoll 注册的事件,比如EPOLLIN、EPOLLOUT等等** */
    epoll_data_t data; /* 见上面的结构体 */
};
op参数说明操作类型:
EPOLL_CTL_ADD:向interest list添加一个需要监视的描述符
EPOLL_CTL_DEL:从interest list中删除一个描述符
EPOLL_CTL_MOD:修改interest list中一个描述符
fd参数表示要监听的fd

2.3 、epoll_wait()

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
功能:阻塞等待注册事件的发生,返回事件的数目,并将触发的事件写入events数组中
events: 用来记录被触发的events,其大小应该和maxevents一致
maxevents: 返回的events的最大个数

timeout描述在函数调用中阻塞时间上限,单位是ms:
timeout = -1表示调用将一直阻塞,直到有文件描述符进入ready状态或者捕获到信号才返回;
timeout = 0用于非阻塞检测是否有描述符处于ready状态,不管结果怎么样,调用都立即返回;
timeout > 0表示调用将最多持续timeout时间,如果期间有检测对象变为ready状态或者捕获到信号则返回,否则直到超时。

3、触发方式

epoll监控多个文件描述符的I/O事件
epoll支持边缘触发(edge trigger,ET)或水平触发(level trigger,LT),通过epoll_wait等待I/O事件,如果当前没有可用的事件则阻塞调用线程。
select和poll只支持LT工作模式,epoll的默认的工作模式是LT模式。

3.1、水平触发

对于读操作,只要缓冲内容不为空,LT模式返回读就绪。
对于写操作,只要缓冲区还不满,LT模式会返回写就绪。

3.2、边缘触发

对于读操作
当缓冲区由不可读变为可读的时候,即缓冲区由空变为不空的时候。
当有新数据到达时,即缓冲区中的待读数据变多的时候。
当缓冲区有数据可读,且应用进程对相应的描述符进行EPOLL_CTL_MOD 修改EPOLLIN事件时。
对于写操作
当缓冲区由不可写变为可写时。
当有旧数据被发送走,即缓冲区中的内容变少的时候。
当缓冲区有空间可写,且应用进程对相应的描述符进行EPOLL_CTL_MOD 修改EPOLLOUT事件时。

posted @ 2021-08-18 15:33  summerL  阅读(329)  评论(0)    收藏  举报