linux - 为什么在这种情况下会发生优先级反转 - Linux?

标签 linux multithreading thread-priority

我已经阅读了很多关于优先级反转的帖子,但我仍然无法阐明我对某些部分的理解。如果有人能阐明我的问题,我会很高兴。

先描述一下情况吧。我有一个伪代码,这是不言自明的。

我有一个共享资源 - int t;这是将由三个线程执行的函数 - 低优先级任务 p1、中优先级任务 p2、高优先级任务 p3。

/**Shared resource **/
int t;

/** Function that will be executed by three threads **/

void func()
{
   printf("hello..world");    /** line number 11**/
   mutex_lock(&lock);         /** line number 12**/
   {                          /** line number 13**/
      for(int i = 0; i<=100; i++) /** line number 14**/
      {                          /** line number 15**/
         t++;                   /** line number 16**/
      }                         /** line number 17**/

   }                            /** line number 18**/

   mutex_unlock(&lock);        /** line number 19**/

}                              /** line number 20**/

假设 p1(low p).. 开始执行 func()。现在假设它在第 13 行。在互斥锁之后。意思是说 p3 ..开始运行。现在,p3 将被阻塞,因为 p1 在临界区中。因此,p3 进入阻塞状态。

场景 - p1 - 临界区内 - 处于运行状态。 p3 - 阻塞状态。

现在,假设 p2 开始运行。由于 p2 处于运行状态,它也会被 p1 阻塞,因为 p2 在临界区。那么这里怎么会发生优先级倒置呢?事后我缺少理解,请解释一下..

我下面的理解是否正确?如果不是,请更正。 当p2任务发生优先级反转时应该是什么情况?我知道 p2 开始运行时会发生优先级反转。 p2完成后,p1开始运行。而 p3 永远没有机会。或者可能是在 p2 完成后,p3 运行。这使得 p3 延迟。在这种情况下,可能会发生互斥锁超时。

这是其中一种情况 - 我们软件中的错误。由于互斥锁超时而发生崩溃的地方。发生这种情况是因为有人说优先级倒置。这是通过将 mutex 属性设置为优先级继承来解决的。我试图对修复进行事后分析,但我坚持优先级倒置的基本原理。我读过很多帖子 - Mars path finder,但我的问题仍然存在。请在这里帮助我。

最佳答案

如果 p2 也等待互斥量,则不会发生优先级反转问题。在这种情况下,p1 运行直到完成,然后解锁互斥锁,调度程序可以接下来调度 p3。

假设 p2 没有等待。相反,它做了一些完全不同的事情,这需要大量的 CPU 周期。当 p2 运行时,p1 将获得很少或没有 CPU 资源。所以 p1 永远不会(或在很长一段时间后)完成并解锁互斥量。当 p2 最终完成并且不再使用 CPU 时,p1 将再次获得 CPU 时间,完成并解锁互斥锁。现在 p3 可以继续了。

在那种情况下,p3 必须等到 p2 完成,即使 p3 的优先级高于 p2。

当所有线程都在竞争相同 资源时,优先级反转问题不是问题。当涉及不同资源(在我的示例中,互斥锁和 CPU 时间)时,这是一个问题,一个低优先级线程阻塞了一个资源,一个高优先级线程正在等待该资源,但是低优先级线程优先级线程无法释放其资源,因为中优先级线程阻止低优先级线程运行。

优先级继承的作用是:在p3等待互斥量的同时,p1会“继承”p3的优先级。所以 p1 将获得 CPU 而不是 p2,这意味着它可以完成其任务并尽快释放互斥量。一旦 p1 释放了 mutex,它会恢复到它自己的优先级,调度器将允许 p3 运行(因为 p1 已经完成并且 p2 的优先级低于 p3)。

关于linux - 为什么在这种情况下会发生优先级反转 - Linux?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20867207/

相关文章:

linux - 使用 lsof 检查文件是否打开

linux - unix 中的输出变量,换行符为\n

java - ShutdownHook何时被调用?

java - 测试线程优先级。为什么在某些情况下低优先级线程更快?

linux - 如何在 bash 中将多个结果从一个命令发送到另一个命令?

linux - echo - 语法错误 : Bad substitution

c - Gcc 优化条件

c++ - std::thread 和异常处理

java - "nice"是否影响Java线程的优先级

Java-Thread.setPriority()错误: cannot find symbol (the period between Thread and setPriority)