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














