什么是优先级倒置?


Answers:


59

优先级倒置是一个问题,而不是解决方案。典型示例是低优先级进程获取高优先级进程需要的资源,然后被中优先级进程抢占,因此,高优先级进程在中优先级进程完成时被阻止在资源上(有效地执行较低的优先级)。

一个相当著名的例子是火星探路者漫游车遇到的问题:http : //www.cs.duke.edu/~carla/mars.html,这是一个很有趣的读物。


19
我很困惑!为什么高优先级进程不能从一开始就抢占低优先级进程?中优先级进程可以做到这一点,当然高优先级进程也必须能够做到这一点吗?我现在已经阅读了很多关于该主题的解释,但是我觉得还缺少一些东西。
维克多

1
假设HP流程会定期生产,因此其他流程也会运行。仅当它试图获取LP已经拥有的资源时,问题才会出现。
德米特里(Dmitri)

20
@Viktor高优先级任务不会100%地运行。而且当它不运行时,低优先级的任务可能随之而来,并抢占了一个互斥体。在工作的中间,出现了中等过程,抢占了运行缓慢的任务。然后,高优先级任务唤醒,并希望获取低优先级任务现在拥有的互斥体。但是高优先级任务现在无法获取互斥锁-它由低优先级进程拥有-因此现在出现了一个问题,高优先级任务无法继续进行。
2014年

16
@Viktor我也感到困惑,但是关键的信息是高优先级线程和低优先级线程有一个共同的互斥体。高优先级线程无法抢占低优先级线程,因为它们试图利用相同的资源,并且必须等待低优先级完成。另一方面,中优先级线程可以控制,因为它不依赖于相同的共享资源。因此,中优先级线程将低优先级线程置于睡眠状态并接管。
Nattrass 2015年

1
nos + Nattrass的答案是完美的!
卡米诺2015年

71

想象一下具有不同优先级的三(3)个任务:tLow,tMed和tHigh。tlow和tHigh在不同时间访问相同的关键资源;tMed做自己的事。

  1. tLow正在运行,tMed和tHigh目前被阻止(但不在关键区域)。
  2. tLow出现并进入关键部分。
  3. tHigh将解除阻止,并且由于它是系统中优先级最高的任务,因此它将运行。
  4. 然后,tHigh尝试输入关键资源,但由于其中存在tLow而阻塞。
  5. tMed不受阻碍,并且由于它现在是系统中优先级最高的任务,因此它将运行。

在tLow放弃资源之前,tHigh无法运行。tMed阻塞或结束之前,tLow无法运行。任务的优先级已经颠倒了;尽管tHigh具有最高优先级,但它位于执行链的底部。

为了“解决”优先级反转,必须将tLow的优先级提高到至少与tHigh一样高。有些人可能会将其优先级提高到可能的最高优先级。与提高tLow的优先级一样重要,是在适当的时间降低tLow的优先级。不同的系统将采用不同的方法。

何时降低tLow的优先级...

  1. tLow拥有的任何资源都不会阻塞其他任务。这可能是由于超时或资源释放造成的。
  2. 没有其他有助于提高tLow优先级的任务会被tLow拥有的资源阻止。这可能是由于超时或资源释放造成的。
  3. 当任务等待资源发生变化时,请降低tLow的优先级以匹配在其资源上被阻止的最高优先级任务的优先级。

方法2是方法1的改进,它缩短了tLow优先级达到极限的时间。请注意,在此期间,其优先级保持在tHigh的优先级。

方法3使tLow的优先级在必要时逐步降低,而不是一个全有或全无的步骤。

不同的系统将根据它们认为重要的因素来实施不同的方法。

  • 内存占用
  • 复杂
  • 实时响应
  • 开发人员知识

希望这可以帮助。


1
谢谢。我曾经负责为商业RTOS实现优先级继承算法-娱乐时间。:)
Sparky

@Sparky那么在步骤4中将tLow赋予tHigh优先级,直到tLow解除对关键部分的阻塞,这是正确的吗?
JohnnyFromBF 2015年

@Ian-当具有优先级反转保护时,您可以期望给tLow一个至少等于tHigh的优先级。它将保持该优先级,直到tHigh在该资源上不再(可能更长)被阻止为止。
Sparky 2015年

很好的解释,但是我会把调度程序显式地带到图片中,因为这样可以解决整个问题。
AVP

18

这是问题而不是解决方案。

它描述了一种情况,当低优先级的线程在其工作期间获得锁时,高优先级的线程将不得不等待它们完成(由于它们是低优先级,这可能会花费特别长的时间)。这里的反转是,高优先级的线程直到低优先级的线程才能继续,因此实际上它现在的优先级也较低。

常见的解决方案是让低优先级的线程临时继承所有等待持有锁的人的高优先级。


18

假设一个应用程序具有三个线程:

Thread 1 has high priority.
Thread 2 has medium priority.
Thread 3 has low priority.

假设线程1和线程3共享相同的关键部分代码

在示例开始时,线程1和线程2处于休眠或阻塞状态。线程3运行并进入关键部分。

这时,线程2开始运行,抢占线程3,因为线程2具有更高的优先级。因此,线程3继续拥有关键部分。

稍后,线程1开始运行,抢占线程2。线程1尝试进入线程3拥有的关键部分,但是由于它是另一个线程拥有的,因此线程1阻塞,等待关键部分。

此时,线程2开始运行,因为它的优先级高于线程3,并且线程1没有运行。线程3永远不会释放线程1正在等待的关键部分,因为线程2继续运行。

因此,系统中优先级最高的线程,线程1,被阻塞,等待较低优先级的线程运行。


4
比上述所有示例更好的解释
aknon

以及如何解决这个问题。我猜想在线程1要进入关键部分时,线程3将被赋予线程1优先级。因为那时不安排线程2,而是安排线程3,对吗?
JohnnyFromBF 2015年

2
值得一提的是,2线程不必等待,因为它有自己的代码块来执行,并且不具有相同的关键部分代码来执行的线程1和3
阿布舍克巴拉吉[R

5

[假设,低处理= LP,中处理= MP,高处理= HP]

LP正在执行关键部分。进入临界区时,LP必须已获得某个对象的锁定,例如OBJ。LP现在位于关键区域内。

同时,创建了HP。由于具有更高的优先级,CPU会进行上下文切换,并且HP现在正在执行(不是同一关键部分,而是其他一些代码)。在HP执行过程中的某个时刻,它需要在同一OBJ上锁定(可能在同一关键部分上,也可能不在同一关键部分上),但是OBJ上的OBJ锁定仍然保留,因为它在执行关键部分时被抢占。LP现在无法放弃,因为进程处于READY状态,而不是RUNNING。现在,HP移至BLOCKED / WAITING状态。

现在,MP进入了,并执行自己的代码。MP不需要锁定OBJ,因此可以继续正常执行。HP等待LP释放锁定,而LP等待MP完成执行,以便LP可以返回到RUNNING状态(执行并释放锁定)。只有在LP释放锁定后,HP才能返回READY(就绪,然后通过抢占低优先级任务进入RUNNING)。

因此,有效地意味着,在MP完成之前,LP无法执行,因此HP无法执行。因此,似乎HP正在等待MP,即使它们没有通过任何OBJ锁直接相关。->优先级倒置

优先级反转的一种解决方案是优先级继承-

将进程(A)的优先级增加到等待A具有资源锁的任何其他进程的最大优先级。


2

优先级反转是较低优先级进程获取较高优先级进程需要的资源的地方,从而阻止了较高优先级进程继续进行直到释放资源。

例如:FileA需要由Proc1和Proc2访问。Proc 1具有比Proc2更高的优先级,但是Proc2设法首先打开FileA。

通常,Proc1的运行频率可能是Proc2的10倍,但由于Proc2正在保存文件,因此无法执行任何操作。

因此,最终发生的事情是Proc1阻塞,直到Proc2完成FileA的处理为止,而实际上Proc2保留了FileA的句柄时,它们的优先级被“反转”了。

就“解决问题”而言,如果优先级倒置不断发生,它本身就是一个问题。最坏的情况(大多数操作系统不会让这种情况发生)是如果Proc1才允许Proc2运行。这将导致系统锁定,因为Proc1将继续获得分配的CPU时间,而Proc2将永远不会获得CPU时间,因此该文件将永远不会被释放。


1
我认为您在解释阻塞而不是优先级倒置。当中等优先级进程在较高优先级进程之前运行时,由于较低优先级进程占用了较高优先级进程所需的资源,因此发生优先级反转。此外,您得出结论“文件将永远不会被释放”。您的示例只有2个进程。如果用FileA完成Proc1,它将释放文件。如果忘记这样做,那将是编程不佳而不是优先级反转的问题。
Pavan Manjunath 2014年

2

让我使其非常简单明了。(此答案基于上面的答案,但以清晰的方式呈现)。

假设有一个资源R和3个流程。LMH。哪里p(L) < p(M) < p(H)(哪里p(X)是的优先级X)。

  • L开始首先执行并抓住R。(独家访问R
  • H稍后再出现,并且还希望对其具有独占访问权R,因为LH已经持有,因此必须等待。
  • M来后H它不需要R。而且既然M拥有了它想要执行的一切,它就L不得不离开,因为与相比,它具有更高的优先级L。但是H无法执行此操作,因为它已锁定L了执行所需的资源。

现在使问题更加清楚了,实际上M应该等待未发生的问题H完成p(H) > p(M),这本身就是问题所在。如果出现许多进程,例如M不允许L它们执行和释放锁,则锁定H将永远不会执行。在时间紧迫的应用中这可能是危险的

对于解决方案,请参考上述答案:)


1

优先级反转是这样发生的:给定名称为高,中,低优先级的进程H,M和L,只有H和L共享公共资源。

说,L首先获取资源并开始运行。由于H也需要该资源,因此它进入等待队列。M不共享资源,可以开始运行,因此可以。当L以任何方式中断时,M处于运行状态,因为它具有更高的优先级,并且在发生中断的那一刻就在运行。尽管H的优先级高于M,但由于它在等待队列中,因此它无法获取资源,这意味着优先级甚至低于M。在M完成之后,L将再次接管CPU,使H一直等待。


0

如果阻塞的高优先级线程将其高优先级转移到保留在资源上的低优先级线程,则可以避免优先级反转。


0

当较高优先级的进程需要读取或修改当前由较低优先级的进程(或一系列较低优先级的进程)访问的内核数据时,就会出现调度难题。由于内核数据通常是用锁保护的,因此优先级较高的进程将不得不等待优先级较低的进程来填充资源。如果优先级较低的进程被优先级高的另一个进程取代,情况将变得更加复杂。例如,假设我们有三个进程L,M和H,它们的优先级遵循L <M <H的顺序。假定进程H需要资源R,进程L当前正在访问它。等待L使用资源R完成。但是,现在假定进程M可运行,从而抢占了进程L。具有较低优先级的进程(进程M)已影响进程H必须等待L放弃资源R的时间。此问题称为优先级倒置。它仅在具有两个以上优先级的系统中发生,因此一种解决方案是仅两个优先级。但是,这对于大多数通用操作系统来说是不够的。通常,这些系统通过实现优先级继承协议来解决此问题。根据此协议,所有访问较高优先级进程所需资源的进程都将继承较高优先级,直到用相关资源完成这些进程。完成后,它们的优先级将恢复为原始值。在上面的示例中,优先级继承协议将允许进程L临时继承进程H的优先级,从而防止进程M抢占执行。当进程L使用资源R完成时,它将放弃它从H继承的优先级,并承担其原始优先级。由于资源R现在可用,因此下一步将运行进程H(而不是M)。参考:ABRAHAM SILBERSCHATZ


原样

0

考虑具有两个过程的系统,该过程H具有高优先级和L低优先级。调度规则H因其高优先级而在就绪状态下运行。在某个L关键时刻,可以在其关键区域中H开始运行(例如,I / O操作完成)。H现在开始忙于等待,但是由于运行时L从未计划过H,因此L永远不会有机会离开关键部分。所以H永远循环。

这种情况称为Priority Inversion。因为较高优先级的进程正在等待较低优先级的进程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.