IPC 选型
判别规则(核心,唯一要记的)
- 传数据 → 队列;只通知"事件发生了" → 信号量;保护共享资源 → 互斥量;等多个事件组合(与/或)→ 事件组;一对一简单唤醒 → 任务通知(最轻最快)
一句话:"数据找队列,信号找信号量,资源找互斥锁,多事件找事件组,最简单找任务通知。"
抽象描述(一句话本质)
IPC(任务间通信与同步)选型的核心判别 = 你要"传什么"?数据 → 队列;事件/计数 → 信号量;独占资源 → 互斥量;多事件组合 → 事件组;一对一简单唤醒 → 任务通知。三个易错点:信号量不传数据、任务通知默认一对一、队列带数据副本。
五工具选型总表
| 工具 |
传什么 |
适用 |
成本 |
| 队列 |
数据 |
数据流、命令 |
中(复制数据) |
| 信号量 |
事件/计数 |
通知、计数 |
低 |
| 互斥量 |
无(锁) |
资源独占 |
低 + 继承 |
| 事件组 |
事件组合 |
多事件判断(与/或) |
低 |
| 任务通知 |
简单信号 |
一对一简单唤醒 |
最低(32 位、单目标) |
正反例(建立直觉)
- 正例1:ADC 采样 100 字节给显示任务 → 队列
- 正例2:按键中断通知"按键发生了" → 二值信号量(经典)或任务通知(FreeRTOS 官方推荐 ISR→任务 用,最轻)
- 正例3:两个任务独占全局缓冲区 → 互斥量
- 正例4:等"串口帧 OR 定时器到点"任一事件 → 事件组(OR 等待)
- 正例5:生产者每次产出一个数据 → 队列(有数据要传)
- 反例1:以为信号量能传数据 → 不能,只传"事件/资源计数",计数信号量的值只是可用资源个数
- 反例2:以为任务通知能广播 → 经典版只能一对一;多任务通知用信号量(多 take)或新版广播
变体验证(3 题,全过=学会)
- 陷阱题:信号量能传数据吗?要发"具体数值" → 信号量不传数据(只传事件/计数信号),发具体值必须队列
- 陷阱题:一个事件通知多个任务 → 经典任务通知不能(一对一);用信号量(多任务 take)或新版 FreeRTOS 广播
- 生产者产出一个数据给消费者 → 队列(有数据要传)
口述要点(面试怎么讲)
- 结论先行:五口诀选型表
- 队列 vs 信号量的本质区别:传不传数据。信号量只传同步/计数信号;队列传数据副本。实现上二值信号量≈长度 1 的队列(FreeRTOS 内部),但那是实现,语义完全不同
- 任务通知为什么最轻:直接复用任务控制块(TCB)里已有的字段(通知值+状态),不需要分配独立的内核对象(信号量/队列创建时占 RAM 的 struct)→ 省内存;没有入队/出队操作 → 更快。官方推荐 ISR→任务 用任务通知
- 计数信号量 vs 二值信号量:计数信号量用于资源池(多个同类型资源,Take 减 1、Give 加 1,计数值=可用数)或"事件累计到 N 才消费";二值信号量只有 0/1,用于事件发生与否/单一资源
- 任务通知的版本细节:经典 FreeRTOS = 一对一;新版(V11+)引入通知数组和广播,支持多对一/一对多——面试先说经典答案,再补版本演进
- 易错点:信号量不传数据;任务通知经典一对一;队列带数据副本有复制成本
关系网络
| 相邻概念 |
和本主题的关系 |
孤立理解会犯的错 |
| 优先级反转 |
互斥量解决反转,信号量不解决 |
拿信号量当锁 |
| 任务状态机 |
IPC 是 Blocked 的唤醒来源 |
以为 Blocked 只能靠延时 |
| ISR 通信 |
ISR 里用 FromISR 版本的 IPC API |
中断里用普通 API |
| 任务通知 |
最轻 IPC,官方推荐 ISR→任务 |
以为任务通知能传数据/广播 |
学习日期
2026-08-03
每主题一页,复习时只翻本目录。