優先度逆転

Priority inversion occurs when two or more threads with different priorities are in contention to be scheduled. Consider a simple case with three threads: thread 1, thread 2, and thread 3. Thread 1 is high priority and becomes ready to be scheduled. Thread 2, a low-priority thread, is executing code in a critical section. Thread 1, the high-priority thread, begins waiting for a shared resource from thread 2. Thread 3 has medium priority. Thread 3 receives all the processor time, because the high-priority thread (thread 1) is waiting for shared resources from the low-priority thread (thread 2). Thread 2 will not leave the critical section, because it does not have the highest priority and will not be scheduled.

The scheduler solves this problem by randomly boosting the priority of the ready threads (in this case, the low priority lock-holders). The low priority threads run long enough to exit the critical section, and the high-priority thread can enter the critical section. If the low-priority thread does not get enough CPU time to exit the critical section the first time, it will get another chance during the next round of scheduling.

Priority Inversion - Windows applications | Microsoft Docs

優先度逆転は、異なる優先度をもつふたつ以上のスレッドが、スケジューリングを争っている場合に生じます。 スレッドがみっつある簡単な状況を例にしましょう。 スレッド1は高優先度で、スケジュール待ちの準備状態にあります。 スレッド2は低優先度で、クリティカルセクション内のコードを実行中です。 高優先度のスレッド1は、スレッド2が確保した共有資源の待機にはいります。 スレッド3は中優先度です。 そしてスレッド3がすべての実行時間を消費することになります。 というのも高優先度スレッド(スレッド1)は共有資源を待機しているからで、その資源は低優先度のスレッド(スレッド2)が確保しているためです。*1 スレッド2はクリティカルセクションから出られません。 スレッド2は最高優先度でないため、スケジューリングされないためです。*2

スケジューラーはこの問題を、準備状態のスレッドの優先度をランダムにブーストすることで解決します(この例では、低優先度のロックを獲得したスレッドをブーストする)。 低優先度のスレッドはクリティカルセクションを抜けるのに十分なだけ実行され、高優先度のスレッドはクリティカルセクションに入れるようになります。 仮に低優先度のスレッドがクリティカルセクションを抜けるために十分な CPU 時間を一回では確保できなかったとしても、つぎのスケジューリングのときに別の時間を受け取るチャンスが生まれます。

*1:訳注:スレッド2は低優先度のため、中優先度のスレッド3のスケジューリングが優先され、スレッド2が共有資源を開放する時間が与えられない。 このため中優先度のスレッドが高優先度のスレッドを差し置いて全 CPU 時間を使用するという優先度逆転現象が起きる。

*2:訳注:ここでは優先度が高いスレッドがいれば、それより低い優先度のスレッドに実行時間が与えられないスケジューラーを仮定しているようである。