Deadlocks — Prevention, Avoidance, Banker's Algorithm
1224 words
6 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Deadlocks — Prevention, Avoidance, Banker's Algorithm ## 🎯 Learning Objectives - Identify the four necessary conditions for deadlock - Draw and interpret Resource Allocation Graphs - Apply Banker's Algorithm to determine safe states - Compare deadlock prevention, avoidance, detection, and recovery * * * ## 1. Dea...

Deadlocks — Prevention, Avoidance, Banker's Algorithm
🎯 Learning Objectives
- Identify the four necessary conditions for deadlock
- Draw and interpret Resource Allocation Graphs
- Apply Banker's Algorithm to determine safe states
- Compare deadlock prevention, avoidance, detection, and recovery
1. Deadlock Characterization
1.1 Intuition
A deadlock is like a four-way traffic jam where each car is waiting for another to move, and none can proceed. In operating systems, it's a set of processes where each process is waiting for a resource held by another process in the set.
1.2 Four Necessary Conditions
All four conditions must hold simultaneously for deadlock to occur:
(Diagram)
| Condition | Description | Real-world Analogy |
|---|---|---|
| Mutual Exclusion | Only one process can use a resource at a time | A bathroom can be used by one person |
| Hold and Wait | A process holds resources while waiting for others | Holding your towel while waiting for the shower |
| No Preemption | Resources cannot be forcibly taken away | Can't take someone's parking spot |
| Circular Wait | A cycle of processes each waiting for another | Four cars at a blocked intersection |
1.3 Resource Allocation Graph (RAG)
A directed graph showing resource assignments and requests:
(Diagram)
Cycle in RAG → possible deadlock. But a cycle without multiple resource instances may be a false positive.
| Graph Feature | Meaning |
|---|---|
| P → R (request edge) | Process P is waiting for resource R |
| R → P (assignment edge) | Resource R is allocated to process P |
| Cycle, single-instance resource | Deadlock |
| Cycle, multi-instance resource | Possible deadlock (need further analysis) |
2. Deadlock Prevention
Prevent at least one of the four conditions:
| Condition | Prevention Strategy | Problem |
|---|---|---|
| Mutual Exclusion | Use sharable resources | Not possible for some resources |
| Hold and Wait | Require all resources at once | Low resource utilization |
| No Preemption | Allow preemption | Complex to implement |
| Circular Wait | Impose a global resource ordering | May be difficult to order all resources |
Circular Wait Prevention: Resource Ordering
c// Define a global total order: R1 < R2 < R3 < ... // Every process must request resources in increasing order // WRONG (potential deadlock): void thread1() { lock(mutex1); // R1 lock(mutex2); // R2 } void thread2() { lock(mutex2); // R2 lock(mutex1); // R1 - wait! thread1 holds R1 } // CORRECT (prevents circular wait): void thread1() { lock(mutex1); // Lower order first lock(mutex2); // Higher order } void thread2() { lock(mutex1); // Same order lock(mutex2); }
3. Deadlock Avoidance (Banker's Algorithm)
3.1 Intuition
The banker knows each customer's maximum loan need and only approves loans if the bank would remain in a safe state — where all customers can eventually finish. Similarly, the OS only allocates resources if the system remains safe.
3.2 Data Structures
| Structure | Description |
|---|---|
| Available[m] | Number of available instances of each resource type |
| Max[n][m] | Maximum demand of each process |
| Allocation[n][m] | Currently allocated resources |
| Need[n][m] | Remaining need = Max - Allocation |
3.3 Safety Algorithm
pseudo1. Work = Available, Finish[i] = False for all i 2. Find i such that Finish[i] == False && Need[i] <= Work 3. If found: Work += Allocation[i], Finish[i] = True, goto 2 4. If all Finish[i] == True → system is SAFE
3.4 Worked Example 1
| Process | Allocation (A, B, C) | Max (A, B, C) | Need (A, B, C) |
|---|---|---|---|
| P0 | (0, 1, 0) | (7, 5, 3) | (7, 4, 3) |
| P1 | (2, 0, 0) | (3, 2, 2) | (1, 2, 2) |
| P2 | (3, 0, 2) | (9, 0, 2) | (6, 0, 0) |
| P3 | (2, 1, 1) | (4, 2, 2) | (2, 1, 1) |
| P4 | (0, 0, 2) | (5, 3, 3) | (5, 3, 1) |
Available: (3, 3, 2)
Tracing Safety Algorithm:
| Step | Work | Find | Finish |
|---|---|---|---|
| 0 | (3,3,2) | — | [F,F,F,F,F] |
| 1 | (3,3,2) | P1 needs (1,2,2) ≤ (3,3,2) ✓ | P1 finishes |
| 2 | (3,3,2)+(2,0,0)=(5,3,2) | P3 needs (2,1,1) ≤ (5,3,2) ✓ | P3 finishes |
| 3 | (5,3,2)+(2,1,1)=(7,4,3) | P0 needs (7,4,3) ≤ (7,4,3) ✓ | P0 finishes |
| 4 | (7,4,3)+(0,1,0)=(7,5,3) | P2 needs (6,0,0) ≤ (7,5,3) ✓ | P2 finishes |
| 5 | (7,5,3)+(3,0,2)=(10,5,5) | P4 needs (5,3,1) ≤ (10,5,5) ✓ | P4 finishes |
Safe sequence: P1 → P3 → P0 → P2 → P4 ✓ SAFE
3.5 Worked Example 2: Request Evaluation
From the safe state above, P1 requests (1, 0, 2):
- Check: Request ≤ Need? (1,0,2) ≤ (1,2,2) ✓
- Check: Request ≤ Available? (1,0,2) ≤ (3,3,2) ✓
- Pretend allocate:
| Process | Allocation | Need | Available |
|---|---|---|---|
| P0 | (0,1,0) | (7,4,3) | (2,3,0) |
| P1 | (3,0,2) | (0,2,0) | |
| P2 | (3,0,2) | (6,0,0) | |
| P3 | (2,1,1) | (2,1,1) | |
| P4 | (0,0,2) | (5,3,1) |
- Check safety:
| Step | Work | Find |
|---|---|---|
| 0 | (2,3,0) | — |
| 1 | (2,3,0) | P1 needs (0,2,0) ≤ (2,3,0) ✓ |
| 2 | (2,3,0)+(3,0,2)=(5,3,2) | P3 needs (2,1,1) ≤ (5,3,2) ✓ |
| 3 | (5,3,2)+(2,1,1)=(7,4,3) | P0 needs (7,4,3) ≤ (7,4,3) ✓ |
| ... | Continue | All finish |
Result: SAFE — grant the request!
3.6 Worked Example 3: Unsafe State
Consider the previous state but P0 requests (0, 2, 0) instead:
After pretend allocation, Available = (1, 1, 2).
Safety check fails: Need[i] ≤ Work is false for all unfinished processes.
| Process | Need | Available |
|---|---|---|
| P0 | (7,2,3) | (1,1,2) — no |
| P1 | (1,2,2) | (1,1,2) — no |
| P2 | (6,0,0) | (1,1,2) — no |
| ... |
Result: UNSAFE — deny the request (P0 must wait).
4. Deadlock Detection
4.1 Detection Algorithm (Single Instance)
Use wait-for graph (simplified RAG with only processes):
(Diagram)
Cycle in wait-for graph → deadlock detected!
4.2 Detection Algorithm (Multi-Instance)
Similar to Banker's but using Request matrix:
pseudo1. Work = Available 2. For all processes with Allocation[i] == 0, Finish[i] = True 3. Find i: Finish[i] == False && Request[i] <= Work 4. If found: Work += Allocation[i], Finish[i] = True, goto 3 5. If any Finish[i] == False → deadlocked
5. Deadlock Recovery
| Method | Description | Pros | Cons |
|---|---|---|---|
| Process Termination | Kill one or more deadlocked processes | Simple | Data loss, partial restart |
| Resource Preemption | Take resources from processes | Avoids killing | Rollback complexity, starvation |
| Checkpoint-Restart | Periodically save state, rollback | Clean recovery | High overhead |
6. 📐 Key Formulas / Concepts
| Concept | Formula/Definition |
|---|---|
| Need | Need[i][j] = Max[i][j] - Allocation[i][j] |
| Safe state | There exists a sequence where all processes can finish |
| Request grant | Request ≤ Need AND Request ≤ Available AND resulting state is safe |
| Circular wait | Cycle in RAG (single instance) or RAG analysis (multi-instance) |
7. 📝 Practice Questions
Q1: List the four necessary conditions for deadlock. Which one does resource ordering prevent?Answer: Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait. Resource ordering prevents Circular Wait. Q2: Consider a system with 5 processes and resource A (10 instances). Allocation: P0:3, P1:2, P2:4, P3:1, P4:0. Available:0. All processes need 5 max. Is there deadlock?Answer: Total allocated = 3+2+4+1+0 = 10. Available = 0. Need: P0=2, P1=3, P2=1, P3=4, P4=5. With Available=0, none can proceed → Deadlock (all four processes P0-P3 are blocked waiting for resources held by each other). Q3: Explain the difference between deadlock prevention and deadlock avoidance.Answer: Prevention ensures at least one of the four conditions never holds (static design). Avoidance allows deadlock-prone conditions but dynamically checks each resource request against a safety criterion (like Banker's) before granting it. Prevention is simpler but more restrictive; avoidance gives better resource utilization. Q4: In Banker's algorithm, what is a safe state? Give an example of an unsafe state that is not deadlocked.Answer: A safe state has at least one sequence where each process can eventually finish. An unsafe state has no such sequence but is not yet deadlocked — processes can still execute. Example: If a process holds one unit and needs two more, but only one is left in the pool, the system is unsafe (can't guarantee progress) but not deadlocked (no circular wait yet). Q5: How does a wait-for graph differ from a Resource Allocation Graph?Answer: A wait-for graph shows only processes (edges P1→P2 means P1 is waiting for a resource held by P2). RAG shows both processes and resources. The wait-for graph is a simplified view derived from RAG by removing resource nodes and condensing paths. A cycle in either indicates possible deadlock.
8. 🔗 Cross-References
- Week 5 - Synchronization: Mutex locking patterns that cause deadlocks
- Week 4 - Priority Scheduling: Priority inversion can be mitigated with priority inheritance
- BSCS4021 (Advanced Algorithms): Cycle detection, graph algorithms Join Discord PreviousSynchronizationNextMemory Management