二值信号量 vs 互斥量(Mutex)核心区别

二值信号量 vs 互斥量(Mutex)核心区别

一、本质定位不同

  1. 二值信号量本质是长度为 1 的普通队列,主打任务同步(事件通知),也能临时做互斥,但不推荐。 设计初衷:A 任务 / 中断通知 B 任务 “某件事发生了”。
  2. 互斥量(互斥信号量)是带优先级继承的特殊二值信号量,专门用于共享资源互斥访问。 设计初衷:保护串口、全局变量、外设等独占资源,解决优先级反转。

二、初始值不一样

  1. xSemaphoreCreateBinary()创建二值信号量: 默认计数值 =0(无令牌,不可获取)适合同步:等待中断 / 其他任务释放信号量。 若想初始可用,必须手动调用一次xSemaphoreGive()
  2. xSemaphoreCreateMutex()创建互斥量: 内部自动执行一次 Give,初始计数值 =1(自带令牌,直接上锁)符合互斥场景:资源默认空闲,任务直接 Take 占用。

三、是否具备优先级继承(最关键差异)

  1. 二值信号量:无优先级继承会出现严重优先级反转。 举例:低优先级任务持有信号量,中优先级任务持续运行,高优先级任务卡死等待。
  2. 互斥量:自带优先级继承机制高优先级任务等待被低优先级持有的互斥锁时,临时抬高低优先级任务到高优先级,避免中等优先级任务抢占,大幅降低优先级反转危害。

先讲清楚:无优先级继承时的优先级反转完整场景

任务优先级:高 (H) > 中 (M) > 低 (L)

  1. 低优先级 L 先拿到互斥量,开始运行临界区;
  2. 此时中等优先级 M 就绪,CPU 抢占 L,L 暂停、锁还握在手里;
  3. 高优先级 H 就绪,需要同一把互斥锁,只能阻塞等待 L 释放锁;
  4. 现在局面:高 H 阻塞、低 L 被中 M 抢占、M 持续占用 CPU 无限跑结果:高优先级任务被中等优先级任务长时间阻塞,这就是优先级反转,系统实时性严重破坏。

互斥量优先级继承(Priority Inheritance Protocol,PIP)解决逻辑

核心规则:高优先级任务阻塞在低优先级持有的互斥锁上时,临时把持有锁的低优先级任务优先级提升到当前等待它的最高优先级。 还是上面 H>M>L 场景分步拆解:

  1. L 获取互斥锁,以低优先级运行临界区;
  2. M 就绪,准备抢占 L;
  3. 此时高优先级 H 就绪,申请同一互斥锁,发现锁被 L 持有,进入阻塞;
  4. 触发优先级继承:系统临时抬高 L 的优先级 = H 的高优先级
  5. L 现在优先级等于 H,高于 M,M 无法再抢占 L;