优先级反转
优先级反转是RTOS(实时操作系统)会遇到的一个问题,简单来说就是由于调度原因,让原本优先级较高的任务慢于优先级较低的任务完成,比如下面这种情况,任务1、2、3的优先级依次升高,其中任务1和任务3都需要用到一个共享资源。
- 一开始只有任务1,它成功申请到共享资源。
- t2时刻,优先级更高的任务2抢占了CPU并开始执行,任务1被挂起。
- t3时刻,优先级更高的任务3抢占CPU并开始执行,任务2被挂起。
- t4时刻,任务3申请共享资源,但此时资源被任务1持有,因此任务3进入阻塞状态,任务2获得了CPU。
- t5时刻,任务2完成后,由于共享资源还在任务1手里,因此将会是任务1被调度,而非优先级更高的任务3。
- 直到t6时刻任务1释放了共享资源,任务3才会被调度并执行完毕。
上面这种情况任务的完成顺序是任务2,任务3,任务1。但我们希望的顺序应该是任务3,任务2,任务1。这就发生了优先级反转。
优先级继承
由此就有了第一种解决方案,即优先级继承。
站在任务3的角度,t4~t5这段时间是不希望等待的时间,它更愿意让任务1尽快用完共享资源,这样自己才可以尽快地被调度。
优先级继承就是基于这样一种思想,在高优先级任务被低优先级任务阻塞时,让低优先级任务继承它阻塞了的那个高优先级任务的优先级。 如下图:
- t4时刻任务3申请共享资源,但该资源正在被任务1持有,根据优先级继承,任务1将继承任务3的优先级,因此任务3被阻塞后将会是任务1开始执行,而非之前的任务2。
- t5时刻任务1释放资源,任务3得以获得CPU。
优先级天花板协议
不同之处在于它也给共享资源以优先级,每个资源的优先级是用到它的任务们中的最高优先级,任务的优先级大于资源的优先级时才可以获取它,当一个任务获得共享资源时,它会获得该资源的优先级,并在释放后回到自己之前的优先级。
对于上面的例子,任务1和任务3都用到了共享资源,那么这个资源的优先级就是3(假设越大表示优先级越高),
- t2时刻任务2到来,但任务1在获取资源时就讲自己的优先级调整为3,因此此时任务1的优先级是高于任务2的,任务2不能抢占。
- t3时刻任务1释放资源,它的优先级回到最低,因此被任务3抢占。
- t5时刻任务3完成,任务2优先级高于任务1,获得CPU。