从 Reactor 到 HashMap:一条打通事件驱动与复杂度的学习链路

张开发
2026/4/10 9:58:34 15 分钟阅读

分享文章

从 Reactor 到 HashMap:一条打通事件驱动与复杂度的学习链路
一、为什么要写这篇在学习 C 服务端时我一开始只是“能看懂 Reactor 代码”但始终有几个疑问为什么要用epoll为什么要用unordered_map为什么 handler 要做映射为什么复杂度O(1)、O(n)这么重要 本质问题缺少从“事件驱动模型”到“数据结构与性能”的完整认知链路这篇文章就是把这一整条链路彻底打通。二、Reactor 模型本质1️⃣ 三层角色划分epoll → 发现事件谁有数据 Reactor → 分发事件交给谁处理 handler → 处理事件具体逻辑2️⃣ Reactor 核心代码抽象reactor.add(fd, events, handler); reactor.loop();3️⃣ 两个核心动作 add注册规则(fd, event) → handler loop执行规则等待事件 → 拿到 fd → 查 handler → 执行三、两个 add 的本质区别关键1️⃣ 第一个 addreactor.add(server_fd, EPOLLIN, accept_handler); 作用监听新连接2️⃣ 第二个 addreactor.add(client_fd, EPOLLIN, read_handler); 作用处理连接数据✅ 核心总结一个管接入一个管通信四、为什么 handler 里还能 add因为新连接 新 fd Reactor 是动态事件系统 本质运行过程中不断注册新的事件处理规则五、epoll 的核心机制很多人会误解❗不是“来一个通知一次”而是状态变化才通知示例第1个连接 → 状态变为可读 → 通知 第2个连接 → 仍然可读 → 不通知 第3个连接 → 仍然可读 → 不通知 所以必须while (accept(...) ! -1) {}✅ 核心总结epoll 通知的是“有没有”不是“有多少”六、复杂度最大突破1️⃣ 什么是复杂度数据变多时程序变慢的程度2️⃣ 三种核心复杂度类型含义场景O(1)一步到位哈希查找O(log n)快速缩小范围树查找O(n)一个个找遍历七、为什么 Reactor 必须用 O(1)❌ 如果用 if/else逐个判断 fd → O(n)❌ 如果用遍历扫描所有连接 → O(n)✅ 使用 unordered_maphandlers_[fd]直接定位 → O(1)✅ 核心总结Reactor 的高并发本质依赖 O(1) 查找八、map vs unordered_map彻底搞懂1️⃣ 对比表容器底层结构复杂度unordered_map哈希表O(1)map红黑树O(log n)2️⃣ 一句话本质unordered_map 是“算位置”map 是“走路径”九、红黑树本质不用死磕细节1️⃣ 为什么需要红黑树普通二叉树可能变成链表 → O(n)2️⃣ 红黑树做了什么自动调整 → 保持基本平衡3️⃣ 核心一句话红黑树是一种“不会长歪太严重”的二叉查找树 保证O(log n)十、Java Map 对应关系JavaCHashMapunordered_mapTreeMapmap一句话总结HashMap 是哈希表实现O(1)TreeMap 是红黑树实现O(log n十一、整条知识链最重要Reactor ↓ fd → handler调度 ↓ unordered_mapO(1) ↓ 复杂度性能 ↓ 数据结构哈希 / 红黑树 ↓ 高并发系统设计 本质高并发 事件驱动 O(1) 查找 数据结构支撑十二、总结你必须记住的三句话1️⃣ Reactor 是事件调度系统2️⃣ epoll 负责发现事件unordered_map 负责快速分发3️⃣ 所有高性能系统本质都在降低复杂度十三、后续学习路线 优先级1 哈希表原理为什么 O(1) 优先级2 线程池 并发模型 优先级3 多 Reactor 架构最后一句当你开始从“复杂度”角度看代码时才真正进入工程能力的门槛。

更多文章