Day 2 深入论述:LT vs ET 编程范式与 epoll 设计原理(索引)
本文是 Day 2 的原理深度篇,配合 实践指南 阅读。 主题:LT(水平触发,Level Triggered)与 ET(边缘触发,Edge Triggered)的完整对比、内核通知机制差异、事件注册策略、性能分析、以及典型案例的死锁 Bug 分析。 本文已拆分为 4 篇独立子文档,每篇一个主题、信息量适中,建议按顺序阅读。
阅读路线(推荐顺序)
| 顺序 | 子文档 | 内容 | 篇幅 |
|---|---|---|---|
| 1 | 本质区别与三个关键操作 | 谁在追踪 fd 就绪状态;accept/read/write 三循环范式 | ★ |
| 2 | 事件注册策略差异 | EPOLLOUT 空转、ET 连接挂死、"避免噪音 vs 收到通知" | ★★ |
| 3 | 性能实测与理论分析 | 理论三维度、benchmark 数据(QPS +6.8% / P99 -20% / max -39%)、三版本递进 | ★★★ |
| 4 | LT 状态机死锁 Bug 案例 | 状态机与事件注册脱节导致的真实死锁:现象、根因、修复、教训 | ★★★ |
若只想快速了解:读第 1 篇即可获得"ET 三循环"的核心范式;第 2、3 篇回答"为什么生产环境用 ET";第 4 篇用真实 bug 巩固对事件注册的理解。
全文要点总结
| 要点 | 说明 |
|---|---|
| LT 内核追踪 / ET 自己追踪 | LT 每次 epoll_wait 都重新通知所有就绪 fd,ET 只在 fd 状态变化时通知一次 |
| ET 三循环不可少 | accept/read/write 都必须循环到 EAGAIN,否则数据/连接永久丢失 |
| 事件注册策略差异 | LT 切事件为"避免噪音"(性能优化),ET 切事件为"收到通知"(正确性要求) |
| ET 优势在尾延迟不在 QPS | localhost 回环测算 ET QPS +6.8%,P99 -20%,max -39% |
| Bug 教训 | 状态机状态和 epoll 注册是两个独立维度,必须同步更新 |
一句话总结:LT 以"过度通知"换简单和稳定,ET 以"精确控制"换尾延迟优势。两者的根本区别在于谁来追踪 fd 的就绪状态——LT 交给内核(每次提醒),ET 交给应用自己(只提醒一次)。三个版本(LT / ET 单进程 / ET 多进程)对应三个递进的认知层次。