RTOS 任务同步方式
判别规则(核心,唯一要记的)
按顺序套(是一条判别流水线):
- 先问:传不传数据? 传 → 队列(通信);不传只传信号 → 继续(同步)
- 再问:接收者唯一吗? 唯一(点对点)→ 任务通知(最轻,不建内核对象)
- 不唯一 → 问:组合条件还是计数? 多条件 AND/OR → 事件组;计数积累 / 资源池 / 多接收者 → 信号量
一句话:一对一 → 通知;多条件组合 → 事件组;计数/资源/多对一 → 信号量。
抽象描述(一句话本质)
三种机制都是"任务 A 通知/同步任务 B",区别在通知几个条件、要不要计数、谁接收、开销多大。三者只传信号不传数据,传数据用队列。
正反例(建立直觉)
- 正例1:传感器任务 → 显示任务,"有数据了",固定一对一 → 任务通知(不建内核对象,比信号量快约 45%,省内存)
- 正例2:设备启动 = "温度达标 && 按键按下 && 定时到"三条件都满足才动 → 事件组(位标志集合,一个等待点表达 AND)
- 正例3:UART 每收一字节 ISR 通知主任务,想知道攒了几个 → 信号量(计数是灵魂,每次 give+1)
- 正例4:3 个任务排队独占同一块 SPI → 互斥信号量(资源独占,带优先级继承)
- 反例1:3 个任务各自等同一事件做不同事 → 任务通知不合适(只通知指定一个任务);该用事件组/信号量
- 反例2:条件是"A 或 B 任一满足就继续" → 信号量表达不了"或",事件组的 OR 等待才是正解
- 反例3:纯"等一个条件就继续"、不计数、接收者唯一 → 还建信号量 = 过度设计,任务通知更轻
易混对比
| 维度 |
任务通知 |
事件组 |
信号量 |
| 核心能力 |
一对一快速通知 |
多条件 AND/OR 组合 |
计数积累 / 资源管理 |
| 接收者 |
只能指定一个任务 |
可多任务等 |
可多任务 take |
| 计数 |
无 |
无(只有置位/清位) |
✅ 计数是灵魂 |
| 多条件表达 |
无 |
✅ 位组合,与/或一条指令 |
无(要串多个,复杂) |
| 开销 |
最低(无内核对象) |
中 |
中 |
变体验证(3 题 + 重验,全过=学会)
- 定时器任务每 100ms 唤醒唯一显示任务刷新 → 任务通知(一对一,先问"能不能用任务通知",别一上来就信号量)
- 电梯"门关好 && 楼层选定 && 未超载"三条件都满足才运行 → 事件组(AND 组合等待)
- 陷阱题:关机信号要所有任务都收到做清理 → 有人顺手用任务通知,错。标准答案:事件组(多任务可等同一事件组)。补充:FreeRTOS v10.2.0 起
xTaskNotifyBroadcast() 确实支持广播,但只唤醒正在等该通知的任务,是高级例外,不是选型默认
- 重验:按键 ISR 通知唯一处理任务读键值 → 任务通知(不建内核对象)
口述要点(面试怎么讲)
- 结论先行:选型靠三个问题——传数据吗?接收者唯一吗?组合条件还是计数?
- 为什么任务通知快:直接在接收任务 TCB 的通知值上操作,不创建内核对象、不走队列/链表
- 信号量 vs 事件组表达多条件:事件组是位掩码,与/或一条指令完成;信号量要串成数组,本质是对事件组的笨拙模仿,数组表达不了"或"
- 任务通知边界:接收者唯一 + 语义简单;不限于 ISR→任务,任务→任务照样能发(
xTaskNotify)。踩到多接收者/多条件组合/要计数就换事件组或信号量
- 易错点:拿二值信号量当互斥锁(无优先级继承);用同步机制硬传数据
关系网络
| 相邻概念 |
关系 |
孤立理解会犯的错 |
| IPC 选型(队列) |
队列传数据(通信);这三样传信号(同步) |
用同步机制硬传数据,或用队列做同步 |
| 临界区 / 互斥锁 |
互斥信号量管资源独占,临界区关中断保护共享代码 |
以为互斥锁能治所有并发问题 |
| 优先级反转 |
互斥信号量自带优先级继承,这是它区别于二值信号量的关键 |
拿二值信号量当互斥锁,反转照样发生 |
| 事件组 vs 信号量 |
位集合表达组合条件,计数器表达数量 |
用信号量数组硬凑 OR,又慢又绕 |
学习日期
2026-08-03
每主题一页,复习时只翻本目录。