目录
基本特性
互斥锁也是二值信号量,但是具有优先级继承机制。因此二值信号量用于同步(任务与任务、任务与中断)更好一些,互斥锁用于互斥访问。
本质
互斥锁用于互斥就像是一个令牌一样用于保护资源,当一个任务想要获取这个资源时,先要获得这个令牌,使用完资源后,必须还回令牌,允许其他的任务获得这个资源。
互斥锁与信号量一样有相同的API函数,当一个任务访问的互斥量不是立即有效的,这个时候可以设置一个时间,在这个时间内,这个任务将进入阻塞态。不像二值信号量那样,互斥锁有优先级继承机制。这就意味着当一个高优先级的任务尝试获取互斥锁(令牌)时,这个互斥锁(令牌)被低优先级的用着,低优先级的任务的优先级被系统临时提到了与高优先级任务优先级相同。这种设计机制是为了确保高优先级任务进入阻塞的时间尽可能短,以及将出现的“优先级翻转”危害降到最小。
通俗解释
在创建任务的时候,优先级已经设置好了,高优先级的任务可以打断低优先级的任务,获得CPU的使用权。但是在很多场合中,某些资源只有一个,当低优先级的任务正在使用资源的时候,高优先级任务只能等待。这里高优先级无法优于低优先级运行的现象被称为“优先级翻转”。
“优先级翻转”会导致系统的高优先级任务阻塞时间过长。高优先级的任务可能运行着某些重要任务,导致不能及时运行。
举例理解优先级机制
举个例子,现在有 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 个任务的系统,假如很多个这样子的任务打断最低优先级的任务,那这个系统最高优先级任务岂不是崩溃了,这个现象是绝对不允许出现的,高优先级的任务必须能及时响应。所以,没有优先级继承的情况下,使用资源保护,其危害极大,具体见图:
(1) :L 任务正在使用某临界资源, H 任务被唤醒,执行 H 任务。但 L 任务并未执行完毕,此时临界资源还未释放。
(2) :这个时刻 H 任务也要对该临界资源进行访问,但 L 任务还未释放资源,由于保护机制,H 任务进入阻塞态,L 任务得以继续运行,此时已经发生了优先级翻转现象。
(3) :某个时刻 M 任务被唤醒,由于 M 任务的优先级高于 L 任务, M 任务抢占了 CPU的使用权,M任务开始运行,此时 L任务尚未执行完,临界资源还没被释放。
(4) :M任务运行结束,归还 CPU 使用权,L任务继续运行。
(5) :L 任务运行结束,释放临界资源,H 任务得以对资源进行访问,H 任务开始运行。
在这过程中,H 任务的等待时间过长,这对系统来说这是很致命的,所以这种情况不允许出现,而互斥量就是用来降低优先级翻转的产生的危害。
如果有优先级继承机制,那么在 H 任务申请该资源的时候,由于申请不到资源会进入阻塞态,那么系统就会把当前正在使用资源的 L 任务的优先级临时提高到与 H 任务优先级相同,此时 M 任务被唤醒了,因为它的优先级比 H 任务低,所以无法打断 L 任务,因为此时 L 任务的优先级被临时提升到 H,所以当 L 任务使用完该资源了,进行释放,那么此时 H 任务优先级最高,将接着抢占 CPU 的使用权, H 任务的阻塞时间仅仅是 L 任务的执行时间,此时的优先级的危害降到了最低,具体见图:
(1) :L任务正在使用某临界资源,L任务正在使用某临界资源, H任务被唤醒,执行 H任务。但 L任务并未执行完毕,此时临界资源还未释放。
(2) :某一时刻 H 任务也要对该资源进行访问,由于保护机制,H 任务进入阻塞态。此时发生优先级继承,系统将 L 任务的优先级暂时提升到与 H 任务优先级相同,L任务继续执行。
(3) :在某一时刻 M 任务被唤醒,由于此时 M 任务的优先级暂时低于 L任务,所以 M 任务仅在就绪态,而无法获得 CPU使用权。
(4):L 任务运行完毕,H 任务获得对资源的访问权,H 任务从阻塞态变成运行态,此时 L任务的优先级会变回原来的优先级。
(5) :当 H任务运行完毕,M 任务得到 CPU使用权,开始执行。
(6) :系统正常运行,按照设定好的优先级运行。
互斥锁一般在同一个任务中完成加锁和解锁。
测试程序
待补充。。。