我想知道为什么抢占不能解决优先级倒置问题?
如果我们有抢占式内核。那为什么优先级倒置问题得不到解决呢?
好的,假设我们有两个进程。我们还假设优先级较低的进程获得锁定。当优先级较高的进程准备就绪时,它会抢占另一个进程。如果优先级较高的进程需要该锁,则由于另一个进程的优先级较低,它无法获取该锁。这意味着,优先级较低的进程会阻止优先级较高的进程。它可以防止更高优先级的进程运行。这称为"优先级反转"。
显然,抢占不是优先级倒置的解决方案。解决方案是"优先级继承"。这意味着每当进程获得更高优先级的进程也需要的锁时,我们应该暂时增加进程的优先级。它应该是其他可能需要相同锁的进程中优先级最高的进程。
设 3 个线程 A、B、C 分别具有优先级高、中、低。
C 获取处理器并锁定 L。然后 B 被一些事件唤醒并抢占 C。现在 A 被唤醒并通过抢占 B 来获取处理器。A 想要锁 L,但失败了,因为 L 已经归 C 所有。A 由于锁不可用而被抢占,并将处理器交还给 B。我们必须等待 B 完成,最终会将处理器还给 C。C 将完成并释放锁,最终唤醒 A。
这是一个优先级倒置,因为 B 运行,而系统中有一个优先级较高的线程 A 等待较低优先级线程(在本例中为 C)的完成。
顺便说一下,解决方案是优先级继承。
抢占意味着拿走处理器,以便任务不再运行。
这还不够,因为低优先级任务包含高优先级任务所需的资源。
现在,如果资源可以被带走(一种不同类型的"抢占"),那么这确实可以解决优先级倒置。但这通常是不可能的,因为低优先级任务的半成品操作会导致不一致。
假设您有 3 个进程:
- A - 高优先级
- B - 正常优先级
- C - 低优先级
而且 A 和 C 都使用相同的文件(可以是任何共享资源),其用法必须同步。
现在假设 A 和 B 都没有准备好运行,C 运行并获取锁以使用该文件。当 C 对文件保持锁定时,A 准备运行,操作系统抢占 C 并运行 A。A 执行到它也需要该文件的程度,当它尝试获取锁时,它被阻止,因为 C 持有锁。如果同时 B 准备好运行,它将执行而不是 A,因为 A 尚未准备好运行。为了使 A 准备就绪,C 必须释放文件锁,C 不会运行并释放锁,因为优先级更高的进程 B 正在运行。因此,A 正在等待 C,而 C 又在等待 B。在这种情况下,仅仅抢占 B 是没有好处的,因为 A 还没有准备好,除非 C 运行,否则不会,而 C 不能运行,因为刚刚抢占的更高优先级的 B 已经准备好运行。
来自维基
考虑
L --> 低优先级任务
H --> 高优先级任务
M --> 中等优先级任务
R -->资源
第 1 步:L 获取 R
第 2 步:H 请求 R(当前与 L 一起使用,因此 H 将等待 L 放弃 R。
第 3 步:M 到达(M 是一个非阻塞任务,即它不需要 R)
第 4 步:L 被 M 抢占(因此 L 不能放弃 R.因此,H 无法运行。
在M完成它的执行后,L将放弃R。之后,只有 H 可以继续。在上述场景中,具有中等优先级 (M) 的任务先于具有高优先级 (H) 的任务运行。
这是抢占式内核中的实际优先级倒置场景。
优先级倒置是调度中的一个有问题的场景,当优先级较高的任务被优先级较低的任务间接抢占时,有效地"反转"了两个任务的相对优先级。
考虑有一个任务 L,优先级较低。此任务需要资源 R。假设 L 正在运行并且它获取资源 R。现在,还有另一个任务 H,具有高优先级。此任务还需要资源 R。假设 H 在 L 获取资源 R 后开始。现在 H 必须等到 L 放弃资源 R。到目前为止,一切都按预期工作,但是当新任务 M(不使用 R)在此期间以中等优先级启动时会出现问题。由于 R 仍在使用(由 L 使用),因此 H 无法运行。由于 M 是优先级最高的解锁任务,因此它将在 L 之前调度。由于L已被M抢占,L不能放弃R。所以 M 会运行直到它完成,然后 L 会运行——至少到它可以放弃 R 的程度——然后 H 会运行。因此,在上面的场景中,具有中等优先级的任务先于具有高优先级的任务运行,从而有效地为我们提供了优先级倒置。