5.对比
机制 | 用途 | 特点 | 适用场景 |
---|---|---|---|
队列(Queue) | 传递数据 | 支持多个数据项排队 | 任务间传递结构体/数值等数据 |
信号量(Semaphore) | 同步 / 互斥 | 不传递数据,只传“信号” | 同步事件、任务间或中断间的配合 |
互斥锁(Mutex) | 资源互斥保护 | 特殊的二值信号量 + 优先级继承 | 多任务访问共享资源(如 I²C、串口) |
事件组(Event Group) | 多位同步控制 | 可同时表示多个状态位 | 控制多个条件满足才执行,如联网、就绪等 |
任务通知(Task Notification) | 点对点通知 + 可传值 | 轻量,效率高,限单任务 | 一对一传递信号或数据 |
🧩 各模块详细对比
1. ✅ 队列(Queue)
可以传递数据(整数、结构体等)
先进先出(FIFO)机制
可以阻塞等待队列满或空
支持任务与任务 / 中断与任务之间通信
🔧 示例用途:
xQueueSend(queue, &data, portMAX_DELAY); // 发送数据 xQueueReceive(queue, &data, portMAX_DELAY); // 接收数据
2. ✅ 信号量(Semaphore)
2.1 二值信号量(Binary Semaphore)
只表示 “有/无” 两种状态,不传值
用于同步(如:等待中断、事件触发)
2.2 计数信号量(Counting Semaphore)
可以累加的“计数器”
适用于某种资源有多个实例
🔧 示例用途:
xSemaphoreGive(binary_sema); // 发送信号(如 ISR 中) xSemaphoreTake(binary_sema, portMAX_DELAY); // 等待信号
3. ✅ 互斥锁(Mutex)
本质是 带优先级继承的二值信号量
专门用于多个任务之间 保护共享资源
只允许一个任务持有,其他任务会阻塞等待
任务释放后会恢复优先级,避免“优先级反转”问题
🔧 示例用途:
xSemaphoreTake(mutex, portMAX_DELAY); // 上锁 // 访问共享资源... xSemaphoreGive(mutex); // 解锁
4. ✅ 事件组(Event Group)
用 位(bit) 表示多个事件状态(最多 24 个位)
支持按位等待“任一位”或“所有位”
适合多个状态控制组合,如:
BIT0 表示联网成功
BIT1 表示传感器初始化完成
BIT2 表示时间同步完成
🔧 示例用途:
xEventGroupSetBits(event_group, BIT0 | BIT2); // 设置位 xEventGroupWaitBits(event_group, BIT0 | BIT2, pdTRUE, pdTRUE, portMAX_DELAY); // 等待两个事件位
5. ✅ 任务通知(Task Notification)
每个任务自带一个“私有”通知通道
可传一个
uint32_t
值效率最高,占用最少
适合一对一通知,不能一对多
🔧 示例用途:
xTaskNotify(task_handle, 1234, eSetValueWithOverwrite); // 发送通知值 xTaskNotifyWait(0, 0, &value, portMAX_DELAY); // 等待并接收通知值
🧪 使用建议总结
如果你要… | 用这个机制 |
---|---|
任务/中断传输数据结构 | ✅ 队列 Queue |
仅通知某事件发生 | ✅ 二值信号量 |
控制资源(如 I2C)访问顺序 | ✅ 互斥锁 Mutex |
等待多个条件状态完成 | ✅ 事件组 Event Group |
轻量、一对一传信号/值 | ✅ 任务通知 Task Notification |
📌 提示
注意点 | 说明 |
---|---|
队列最耗资源 | 占用内存(需内部数组存放数据) |
任务通知最快 | 每个任务只能有一个通知通道,适合一对一 |
事件组不能传值 | 只能用位来表示事件状态 |
信号量没有值 | 不能附带数据,只是“信号” |
互斥锁专用于资源保护 | 不建议用作通用同步机制 |