news 2026/4/18 14:09:29

多路复用epoll

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多路复用epoll

Epoll:性能之王(红黑树+回调)

epoll是为了解决大批量句柄处理而设计的

一、 Epoll 的核心工作原理

要理解 Epoll 的接口,首先要理解它在内核里建立的两个“秘密基地”:

  1. 红黑树 (Red-Black Tree,rbr)
    • 用来存储所有你想要监听的文件描述符(FD)。
    • select每次都要把整个集合传给内核,而 Epoll 把这些 FD 存在内核的红黑树里,不需要重复拷贝。增删查改的效率是O(logN)
  1. 就绪双向链表 (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_event

struct 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就绪链表,如果有数据,就拷贝给用户。
  • 参数详解
    • epfd:Epoll 句柄。
    • events输出参数。这是一个数组,内核会把就绪的事件复制到这里 。
    • maxevents:告诉内核这个数组有多大(不能大于创建时的 size,但现在 size 被忽略,主要是防止数组越界)。
    • timeout:超时时间(毫秒)。0表示立即返回(非阻塞),-1表示永久阻塞,>0表示等待指定时间 。
  • 返回值
    • > 0:就绪的文件描述符个数。
    • 0:超时。
    • -1:出错 。

三、 Epoll 的两种工作模式:LT vs ET

1. LT 模式 (Level Triggered) —— 水平触发
  • 默认模式
  • 机制:只要 socket 接收缓冲区里还有数据,epoll_wait就会一直通知你 。
  • 例子:缓冲区有 2KB 数据,你只读了 1KB。下次调用epoll_wait,它会再次返回并告诉你“有数据读” 。
  • 特点:支持阻塞和非阻塞读写,编程不容易出错 。Select 和 Poll 本质上也是 LT 模式 。
2. ET 模式 (Edge Triggered) —— 边缘触发
  • 高性能模式(Nginx 默认采用)。
  • 机制:只有当状态发生变化时(从无数据变成有数据),内核才会通知一次 。
  • 例子:缓冲区有 2KB 数据,你只读了 1KB。下次调用epoll_wait它不会再通知你了,剩下的 1KB 数据会一直待在缓冲区里,直到下一次有数据到来 。
  • 要求
    1. 必须配合非阻塞 I/O (Non-blocking IO)使用 。
    2. 必须使用循环 (while) 读取,直到read返回EAGAIN错误,确保把缓冲区读空 。
  • 优点:减少了epoll_wait返回的次数,系统调用开销更小 。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 10:36:40

STM32串口DMA多通道并发控制完整示例

STM32串口DMA多通道并发控制实战指南:从原理到工程落地 你有没有遇到过这样的场景?系统里连了GPS、蓝牙模块、PLC控制器,还有上位机调试通道,全都靠串口通信。结果一跑起来,CPU占用飙到80%以上,数据还经常丢…

作者头像 李华
网站建设 2026/4/17 22:33:17

单片机实现USB Host功能的小白指南

让单片机当“电脑”:从零搞懂USB Host功能的实战之路 你有没有想过,让一块小小的单片机像电脑一样,主动读取U盘、接收键盘输入、甚至控制打印机?听起来很酷,但似乎只属于高性能处理器或Linux系统的专利? 其…

作者头像 李华
网站建设 2026/4/17 21:59:46

用Sonic制作跨境电商产品介绍视频,转化率提升显著

用Sonic制作跨境电商产品介绍视频,转化率提升显著 在跨境电商的战场上,消费者不再满足于冷冰冰的产品图和千篇一律的文字描述。他们想要“看见”使用场景、听见真实讲解、感受到品牌温度。然而,传统真人拍摄视频成本高、周期长,多…

作者头像 李华
网站建设 2026/4/18 14:09:06

Photoshop - Photoshop 工具栏(48)3D材质吸管工具

48.3D材质吸管工具从3D对象加载选定的材质。材质预设根据需要选择材质。载入所选材质。点击此按钮可使当前所选材质载入3D材质拖放工具。目标材质显示3D材质吸管工具选定的材质。

作者头像 李华
网站建设 2026/4/18 13:54:39

Photoshop - Photoshop 工具栏(50)图框工具

50.图框工具为图像创建占位符图框。操作方法点击工具栏图框工具。在画布中绘制图框。然后点击移动工具。移动到合适的区域即可。矩形图框点击此选项可创建新的矩形画框。圆形图框点击此选项可创建新的圆形画框。

作者头像 李华
网站建设 2026/4/18 6:40:58

Photoshop - Photoshop 工具栏(51)直排文字蒙版工具

51.直排文字蒙版工具创建直排文字形状的选区。操作方法点击菜单栏-文件-打开打开图像,或直接把图像拖入Photoshop工作区。点击菜单栏直排文字蒙版工具,设置字体各项参数,在图像上生成字体。相当于加了一个文字选区,可以对齐进行移…

作者头像 李华