优先级反转问题
转 https://zhuanlan.zhihu.com/p/146132061
- 线程A在一个比较低的优先级上工作,假设是10。然后在时间点T1的时候,线程A锁定了一把互斥锁,并开始操作互斥数据。
- 这时有个高优先级线程C(比如优先级20)在时间点T2被唤醒,它也需要操作互斥数据。当它加锁互斥锁的时候,因为互斥锁在T1被线程A锁掉了,所以线程C放弃CPU进入阻塞状态,而线程A得以占有CPU,继续执行。
- 事情到这一步还是正确的,虽然优先级10的A线程看上去抢占了优先级20的C线程的时间,但因为程序逻辑,C确实需要退出CPU等完成互斥数据操作后,才能获得CPU。
- 但是,假设我们有个线程B在优先级15上,在T3时间点醒了过来,因为他比当前执行的线程A优先级高,所以它会立即抢占CPU,而线程A被迫进入就绪状态等待。
- 一直到时间点T4,线程B放弃CPU,这时优先级10的线程A是唯一就绪线程,它再次占据CPU执行,最后在T5解锁了互斥锁。
- 在T5,线程A解锁的瞬间,线程C立即获取互斥锁,并在优先级20上等待CPU。因为他比线程A优先级高,系统立刻调度线程C执行,而线程A再次进入就绪状态。
上面的这个时许,线程B从T3到T4占据CPU运行的行为,就是优先级反转。一个优先级15的线程B,通过压制优先级10的线程A,而事实上导致高优先级线程C无法正确得到CPU。这段时间是不可控的,因为线程B可以长时间占据CPU(即使轮转时间片到时,线程A和B都处于可执行态,但是因为B的优先级高,它依然可以占据CPU),结果就是高优先级线程C可能长时间无法得到CPU。
避免优先级反转的几个方法
- 优先级继承
- 该解决方案将正在执行的低优先级任务的优先级临时提升为需要该资源的最高优先级任务。这意味着中等优先级的任务不能干预并导致优先级反转。
- 无阻塞
- 可以通过避免阻塞来避免优先级反转,因为低优先级任务会阻塞高优先级任务。
- 优先级上限
- 所有资源都被分配了一个优先级,该优先级等于任何可能试图声明它们的任务的最高优先级。