Skip to content

Starvation

Category: Hazards · Status: stub · Lessons: chapter 03, When locks go wrong (planned)

One line: A task that is ready never gets to run, or never gets the lock, because others keep being chosen ahead of it.

Also called: resource starvation, thread starvation, fairness.

How it connects

flowchart LR
  n_blocking_the_event_loop["Blocking the event loop"]
  n_deadlock["Deadlock"]
  n_liveness_failure["Liveness failure"]
  n_read_write_lock["Read-write lock"]
  n_starvation["Starvation"]
  n_blocking_the_event_loop -->|can cause| n_starvation
  n_deadlock ---|vs| n_starvation
  n_read_write_lock -->|can cause| n_starvation
  n_starvation -->|is a| n_liveness_failure
  classDef center stroke-width:3px
  class n_starvation center
  classDef outside stroke-dasharray: 4 3
  class n_blocking_the_event_loop,n_deadlock,n_liveness_failure,n_read_write_lock outside

In each language

Rust RwLock: the priority policy depends on the operating system, so a waiting writer may or may not block new readers
Go RWMutex: once a writer waits, new RLock calls block so the writer eventually gets in; select picks among ready cases uniformly at random
Java ReentrantLock takes a fairness flag: when true the longest-waiting thread is favoured, otherwise no access order is guaranteed
Python threading.Lock: which waiting thread proceeds on release is not defined
C# SemaphoreSlim: blocked threads enter in no guaranteed order, neither FIFO nor LIFO
Kotlin Semaphore in kotlinx.coroutines is fair, keeping acquirers in FIFO order
Haskell MVar promises fairness: threads blocked on it are woken in FIFO order
The operating system sched(7) ↗: a runnable SCHED_FIFO thread always preempts a running normal thread, which can then wait indefinitely

Where to read more