liveBook · Manning

Deadlock

As explained in Grokking Concurrency

A deadlock is a concurrency state in which multiple tasks wait indefinitely for resources held by one another, preventing all of them from continuing.

Imagine two philosophers sharing two chopsticks. Each grabs one chopstick and waits for the other, leaving both unable to eat. That same pattern can stop concurrent tasks forever. section 9.2

A deadlock occurs when multiple tasks wait indefinitely for resources held by one another. None can continue, and the program may remain stuck until it is terminated manually. The exact moment of failure can vary because thread scheduling is nondeterministic. section 9.2 section 9.11

Reduce deadlock risk by controlling how tasks acquire resources:

  • Use a consistent lock hierarchy: require every task to acquire multiple locks in the same priority order. section 9.4
  • Recognize that acquiring more than one lock creates deadlock potential, especially when different tasks request them in opposite orders. section 9.2 section 9.4
  • Use resource allocation graphs or lock hierarchies when fixed ordering is impossible; these approaches help detect or prevent cycles but do not guarantee elimination. section 9.4
  • Consider timeouts for blocking attempts so a task does not wait forever when it cannot obtain all required locks. section 9.4
# Chapter 9/deadlock/deadlock.py
if __name__ == "__main__":
    chopstick_a = LockWithName("chopstick_a")
    chopstick_b = LockWithName("chopstick_b")

    philosopher_1 = Philosopher("Philosopher #1", chopstick_a, chopstick_b)
    philosopher_2 = Philosopher("Philosopher #2", chopstick_b, chopstick_a)

    philosopher_1.start()
    philosopher_2.start()

Inspect the Python setup where two philosophers receive the chopsticks in opposite orders, creating the conditions for deadlock. section 9.2

How Grokking Concurrency covers it

How deep it goes
Explains the failure through a two-lock philosopher example and introduces lock ordering, graphs, hierarchies, and timeouts.
Examples
Uses two philosophers, two chopsticks, dumplings, Python locks, and opposing resource-acquisition orders.
What it assumes
Assumes basic concurrent programming, threads, locks, and synchronization primitives while defining deadlock from the beginning.
What you can do after
Diagnose deadlock-prone lock acquisition and apply a consistent resource hierarchy to avoid it.
How it connects
Connects deadlock with concurrency, mutual exclusion, synchronization, livelock, starvation, resource allocation graphs, and lock hierarchies.

Also explained in

Compare how 15 books explain deadlock →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Grokking Concurrency. The section links point to the parts of the book it draws on.