← Concepts

阅读中文版本

Priority Inversion

Priority inversion makes a high-priority task wait on a lock held by a low-priority task that itself cannot run because medium-priority work monopolizes the CPU — famously grounding a Mars probe.

concurrency

Definition

Priority inversion occurs when a lower-priority task holds a resource a higher-priority task needs, while unrelated medium-priority tasks preempt the holder, indirectly delaying the high-priority task beyond all bounds. Mitigations are priority inheritance — the holder temporarily inherits the waiter priority — and priority ceiling protocols.

Context and scope

Real-time and embedded systems, audio pipelines, and any scheduler with task priorities and shared locks. The Mars Pathfinder reset is the canonical incident.

Common misconceptions

  • Priorities alone prevent it — priorities govern the scheduler, not lock holders; the inversion happens precisely between scheduling and locking
  • It only happens in real-time systems — any priority-scheduled threading with shared locks can exhibit it, including OS thread pools with task priorities
  • Disabling interrupts or preemption is the only fix — priority inheritance fixes it without killing concurrency

Anti-patterns

  • Sharing one mutex between fast high-priority and slow maintenance paths without inheritance
  • Task-priority queues layered over a shared thread pool where a low-priority task holds a structure lock
  • Testing only average latency and missing the rare inversion spikes that miss real-time deadlines

Related concepts

Related examples

Authoritative source

https://en.wikipedia.org/wiki/Priority_inversion

What it is

Priority scheduling assumes the most important runnable task runs. A lock breaks the assumption: the important task blocks on a resource, the resource owner is unimportant and runnable-but-preempted, and uninvolved middle-priority tasks keep the owner from finishing. The important task waits for work the scheduler considers beneath it.

How it works

Priority inheritance raises the lock holder to the highest waiting priority until release, so middle-priority tasks cannot preempt the holder. Priority ceiling goes further: acquiring any lock of a known ceiling raises the holder to that ceiling, preventing deadlock and chained inversions. POSIX mutexes expose the protocol attributes.

When to mitigate

Deadline-critical paths, audio callbacks, control loops, and telemetry threads sharing state with best-effort work. Prefer lock-free handoff or message queues between priority classes where feasible.

Pitfalls

Inheritance adds overhead to every lock acquisition, so apply selectively. Unbounded inversion chains — A waits B waits C — need ceiling protocols or redesign. Watchdog resets paper over inversions while corrupting state mid-operation, which is how the Pathfinder bug presented.