A deadlock is two holders each waiting for what the other holds. Nothing can move, and the program looks alive, so the symptom is a hang and not an error.
What you will see
left right
About 2 min of reading
Quick check
Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.
Try It
Check the lock rules.
1
Order taken.
import threading
left = threading.Lock()
right = threading.Lock()
with left, right:
print("both")
Before you run it, say out loud what it will print. Then open the answer.
Before you run it, say out loud what it will print. Then open the answer.
What it prints
left right
Put it in order
Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.
Data Flow
A holder takes the first lock, then the second, a holder in the other order waits forever, and a timeout turns that wait into a value.
1take the first lock
↓
2take the second lock
↓
3the other order waits
↓
4a timeout reports it
Line by line
Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.
import threadingsets nothing on screen
left = threading.Lock()sets nothing on screen
right = threading.Lock()sets nothing on screen
with left, right:sets nothing on screen
print("both")both
Why this worksOrder is the rule
A deadlock needs a cycle. One stated order for every holder removes the cycle, so the fix is a rule and not a patch.
A hang is not a crash
A deadlocked program uses no CPU and raises nothing. A timeout on acquire or a watchdog is what makes it report.
Examples
The safe order
import threading
left = threading.Lock()
right = threading.Lock()
with left:
with right:
print("ok")
Every holder takes the locks in the same order, so a holder can never wait for a lock a slower holder owns.
The other order
import threading
left = threading.Lock()
right = threading.Lock()
with right:
with left:
print("ok")
This body alone is fine. Paired with the order above, one holder can wait for the other and both stop.