📜  优先级倒置:该死的!

📅  最后修改于: 2021-05-20 08:41:23             🧑  作者: Mango

让我们首先将“优先级倒置”放在大背景下,即这是从哪里来的。

在操作系统中,重要的概念之一是任务计划。有几种调度方法,例如“先到先服务”,“循环调度”,基于优先级的调度等。每种调度方法都有其优缺点。您可能已经猜到了,优先级倒置位于基于优先级的计划下。基本上,当OS使用基于优先级的调度时,有时会出现此问题。在基于优先级的调度中,将不同的任务赋予不同的优先级,以便在可能的情况下,较高优先级的任务可以干预较低优先级的任务。

因此,在基于优先级的调度中,如果较低优先级的任务(L)正在运行,并且还需要运行较高优先级的任务(H),则较低优先级的任务(L)将被较高优先级的任务(H)抢占。现在,假设低优先级任务和高优先级任务都需要共享一个公共资源(例如访问同一文件或设备)以完成各自的工作。在这种情况下,由于存在资源共享并且需要任务同步,因此可以使用几种方法/技术来处理这种情况。为了讨论优先级反转,让我们提到一个称为互斥量的同步方法。只是为了重述互斥锁,任务会在进入关键部分(CS)之前获取互斥锁,并在退出关键部分(CS)之后释放互斥锁。在CS中运行时,任务将访问此公共资源。有关此的更多详细信息,请参见此处。现在,假设L和H共享一个共同的临界区(CS),即此CS需要相同的互斥量。

在讨论优先级反转时,让我们研究一些方案。
1)L正在运行,但不在CS中; H需要跑; H优先于L; H开始运行; H放弃或释放控制权; L恢复并开始运行
2)L正在CS中运行; H需要运行,但不需要在CS中运行; H优先于L; H开始运行; H放弃控制; L恢复并开始运行。
3)L正在CS中运行; H还需要在CS中运行; H等待L从CS中出来; L来自CS; H进入CS并开始运行

请注意,以上方案没有显示任何优先级反转的问题(甚至没有方案3)。基本上,只要优先级较低的任务不在共享CS中运行,优先级较高的任务就可以抢占它。但是,如果L在共享CS中运行,并且H也需要在CS中运行,则H等待,直到L从CS中出来。这个想法是CS应该足够小,以免L在CS时导致H等待很长时间。这就是为什么编写CS代码需要仔细考虑的原因。在上述任何一种情况下,都没有发生优先级反转(即优先级反转)的情况,因为任务正在按设计运行。

现在让我们添加另一个优先级为M的任务。现在,任务优先级的顺序为L

4)L正在CS中运行; H还需要在CS中运行; H等待L从CS出来; M中断L并开始运行; M运行到完成并放弃控制; L恢复并开始运行直到CS结束; H进入CS并开始运行。
请注意,L和H都不与M共享CS。

在这里,我们可以看到,M的运行已延迟了L和H的运行。确切地说,H的优先级更高,并且不与M共享CS;但是H必须等待M。这是基于优先级的调度无法按预期工作的地方,因为M和H的优先级被颠倒了,尽管没有共享任何CS。此问题称为优先级倒置。这就是优先级反转!在具有基于优先级的调度的系统中,较高优先级的任务可能会遇到此问题,并且可能导致意外的行为/结果。在通用操作系统中,这可能会导致性能降低。在RTOS中,它可能导致更严重的后果。最著名的“优先级倒置”问题是火星探路者发生的事情。

如果我们有问题,必须为此解决。对于优先级反转,也有不同的解决方案,例如优先级继承等。这将是我们的下一篇文章

但是对于住院患者来说,这可以暂时参考。