目录
(1)水平触发(Level-Triggered,LT)场景介绍:
(2)边沿触发(Edge-Triggered,ET)场景介绍:
1. epoll概要
epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本。它能够显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。
2. 优点
支持大数目的文件描述符:与select相比,epoll不受文件描述符数量的限制。select支持的进程描述符由FD_SETSIZE设置,默认值为1024,而epoll可以支持的最大文件描述符数目通常远大于这个值,具体数目取决于系统内存大小。
效率不会随监听socket数目的增加而线性下降:select采用轮询的方式扫描所有的socket集合,如果socket数量过大且大多数处于idle状态,select的效率会非常低。而epoll只会对活跃的socket进行操作,因此在处理大量并发连接时,epoll的效率远高于select。
提供边缘触发(Edge Triggered)和水平触发(Level Triggered)两种模式:边缘触发模式只在状态发生变化时通知一次,适用于需要高性能的场景;水平触发模式则只要事件未处理就会持续通知,适用于处理流式数据。
3. 工作模式及API
(1)工作模式
epoll主要通过三个系统调用来实现其功能:epoll_create、epoll_ctl和epoll_wait。
epoll_create:创建一个epoll实例,并返回一个文件描述符,用于后续操作。
epoll_ctl:用于向epoll实例中添加、修改或删除需要监听的文件描述符及其事件。操作类型包括EPOLL_CTL_ADD(添加)、EPOLL_CTL_MOD(修改)和EPOLL_CTL_DEL(删除)。
epoll_wait:等待并返回发生在被监听文件描述符上的事件。用户可以通过设置超时时间来控制等待的时间。
(2)API介绍
int epoll_create(int size)
当某个进程调用 epoll_create 方法时,内核会创建一个 eventpoll 对象(也就是程序中 epfd 所代表的对象)。eventpoll 对象也是文件系统中的一员,和 socket 一样,它也会有等待队列。
参数理论上没有意义,但是会与epoll_wait时的maxevents相联动,maxevents不能超过此size值。
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
创建epoll对象后,可以用epoll_ctl添加或删除所要监听的socket
epoll的事件注册函数,它不同于select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。
arg1:epoll_create()的返回值。
arg2:第二个参数表示动作,用三个宏来表示:
EPOLL_CTL_ADD:注册新的fd到epfd中;
EPOLL_CTL_MOD:修改已经注册的fd的监听事件;
EPOLL_CTL_DEL:从epfd中删除一个fd;
arg3:需要监听的fd。
arg4:告诉内核需要监听什么事
events可以以下几个宏的集合:
EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
&nb