2026/5/21 18:29:52
网站建设
项目流程
对门户网站建设的见解,网站域名免费,公司变更证明模板,私人网站服务器免费Epoll#xff1a;性能之王#xff08;红黑树回调#xff09;epoll 是为了解决大批量句柄处理而设计的一、 Epoll 的核心工作原理要理解 Epoll 的接口#xff0c;首先要理解它在内核里建立的两个“秘密基地”#xff1a;红黑树 (Red-Black Tree, rbr)#xff1a;用来存储所…Epoll性能之王红黑树回调epoll是为了解决大批量句柄处理而设计的一、 Epoll 的核心工作原理要理解 Epoll 的接口首先要理解它在内核里建立的两个“秘密基地”红黑树 (Red-Black Tree,rbr)用来存储所有你想要监听的文件描述符FD。select每次都要把整个集合传给内核而 Epoll 把这些 FD 存在内核的红黑树里不需要重复拷贝。增删查改的效率是O(logN)。就绪双向链表 (Ready List,rdlist)用来存储已经就绪有数据来了的事件。当网卡接收到数据会触发回调函数(ep_poll_callback)这个回调函数会自动把活跃的 FD 放入这个链表 5。epoll_wait不需要遍历所有连接只需要检查这个链表是否为空即可复杂度是O(1)二、 Epoll 的三个核心接口详解Epoll 把select那个臃肿的一个函数拆分成了三个步骤分别对应“建群”、“加人”、“等消息” 。1.epoll_create—— 创建管家建群int epoll_create(int size);功能创建一个 Epoll 的句柄在内核中创建一个eventpoll对象。参数size这个参数其实是被忽略的只要填一个大于 0 的数即可 。返回值成功返回一个 epoll 的文件描述符epfd失败返回 -1。注意Epoll 句柄本身也是一个文件描述符占用一个 FD 资源用完后必须调用close()关闭 。2.epoll_ctl—— 管理名单加人/踢人这是 Epoll 与 Select 最大的不同点。Select 是在等待时才给名单Epoll 是提前注册。int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);参数详解epfdepoll_create返回的那个句柄 。op要进行的操作动作用宏表示 EPOLL_CTL_ADD注册新的 FD 。EPOLL_CTL_MOD修改已有的 FD 监听事件 。EPOLL_CTL_DEL从红黑树中删除一个 FD 。fd需要监听的 socket 文件描述符 。event告诉内核你要监听什么事读/写/异常以及你留的“备注数据” 。关键结构体epoll_eventstruct epoll_event { uint32_t events; // 监听的事件类型 epoll_data_t data; // 用户数据给用户自己用的 };events取值EPOLLIN可读包括对端关闭。EPOLLOUT可写 。EPOLLET开启边缘触发模式 (Edge Triggered)。data联合体 这是一个联合体你可以存int fd也可以存void *ptr指针。当事件就绪时内核会把这个data原样还给你。3.epoll_wait—— 等待消息收割int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);功能收集在 Epoll 监控中已经发生的事件 。它直接查看内核的rdlist就绪链表如果有数据就拷贝给用户。参数详解epfdEpoll 句柄。events输出参数。这是一个数组内核会把就绪的事件复制到这里 。maxevents告诉内核这个数组有多大不能大于创建时的 size但现在 size 被忽略主要是防止数组越界。timeout超时时间毫秒。0表示立即返回非阻塞-1表示永久阻塞0表示等待指定时间 。返回值 0就绪的文件描述符个数。0超时。-1出错 。三、 Epoll 的两种工作模式LT vs ET1. LT 模式 (Level Triggered) —— 水平触发默认模式。机制只要 socket 接收缓冲区里还有数据epoll_wait就会一直通知你 。例子缓冲区有 2KB 数据你只读了 1KB。下次调用epoll_wait它会再次返回并告诉你“有数据读” 。特点支持阻塞和非阻塞读写编程不容易出错 。Select 和 Poll 本质上也是 LT 模式 。2. ET 模式 (Edge Triggered) —— 边缘触发高性能模式Nginx 默认采用。机制只有当状态发生变化时从无数据变成有数据内核才会通知一次 。例子缓冲区有 2KB 数据你只读了 1KB。下次调用epoll_wait它不会再通知你了剩下的 1KB 数据会一直待在缓冲区里直到下一次有新数据到来 。要求必须配合非阻塞 I/O (Non-blocking IO)使用 。必须使用循环 (while) 读取直到read返回EAGAIN错误确保把缓冲区读空 。优点减少了epoll_wait返回的次数系统调用开销更小 。