互斥量(优先级翻转)
这里只是总结,大部分内容来自野火FreeRTOS教程。
互斥量正常可用于资源保护,这里很清晰,不多讲。
需要注意的是互斥量不能在中断服务函数中使用,因为其特有的优先级继承机制只在任务起作用,在中断的上下文环境毫无意义。
而比较重要的是优先级继承机制。
互斥量与二值信号量最大的不同是:互斥量具有优先级继承机制,而信号量没有。
也就是说,某个临界资源受到一个互斥量保护,如果这个资源正在被一个低优先级任务使用,
那么此时的互斥量是闭锁状态,也代表了没有任务能申请到这个互斥量,如果此时一个高
优先级任务想要对这个资源进行访问,去申请这个互斥量,那么高优先级任务会因为申请
不到互斥量而进入阻塞态,那么系统会将现在持有该互斥量的任务的优先级临时提升到与
高优先级任务的优先级相同,这个优先级提升的过程叫做优先级继承。这个优先级继承机
制确保高优先级任务进入阻塞状态的时间尽可能短,以及将已经出现的“优先级翻转”危
害降低到最小。
举个例子,现在有 3 个任务分别为 H 任务(High)、M 任务(Middle)、L 任务
(Low),3 个任务的优先级顺序为 H 任务>M 任务>L 任务。正常运行的时候 H 任务可以
打断 M任务与 L 任务,M 任务可以打断 L 任务,假设系统中有一个资源被保护了,此时该
资源被 L 任务正在使用中,某一刻,H 任务需要使用该资源,但是 L 任务还没使用完,H
任务则因为申请不到资源而进入阻塞态,L 任务继续使用该资源,此时已经出现了“优先
级翻转”现象,高优先级任务在等着低优先级的任务执行,如果在 L 任务执行的时候刚好
M 任务被唤醒了,由于 M 任务优先级比 L 任务优先级高,那么会打断 L 任务,抢占了
CPU 的使用权,直到 M 任务执行完,再把 CUP 使用权归还给 L 任务,L 任务继续执行,
等到执行完毕之后释放该资源,H 任务此时才从阻塞态解除,使用该资源。这个过程,本
来是最高优先级的 H 任务,在等待了更低优先级的 L 任务与 M 任务,其阻塞的时间是 M
任务运行时间+L 任务运行时间,这只是只有 3 个任务的系统,假如很多个这样子的任务打
断最低优先级的任务,那这个系统最高优先级任务岂不是崩溃了,这个现象是绝对不允许
出现的,高优先级的任务必须能及时响应。
假如有优先级继承呢?那么,在 H 任务申请该资源的时候,由于申请不到资源会进入
阻塞态,那么系统就会把当前正在使用资源的 L 任务的优先级临时提高到与 H 任务优先级
相同,此时 M 任务被唤醒了,因为它的优先级比 H 任务低,所以无法打断 L 任务,因为
此时 L 任务的优先级被临时提升到 H,所以当 L 任务使用完该资源了,进行释放,那么此
时 H 任务优先级最高,将接着抢占 CPU 的使用权, H 任务的阻塞时间仅仅是 L 任务的执
行时间,此时的优先级的危害降到了最低,看!这就是优先级继承的优势。