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事件时。

浙公网安备 33010602011771号