Deadlock vs Starvation: Key Differences and When to Use Each
deadlock occurs when two or more processes wait indefinitely for resources held by each other, causing a complete halt. Starvation happens when a process waits indefinitely because other higher-priority processes keep getting resources first, preventing it from progressing.Quick Comparison
This table summarizes the main differences between deadlock and starvation in operating systems.
| Factor | Deadlock | Starvation |
|---|---|---|
| Cause | Circular waiting for resources among processes | Indefinite postponement due to priority or scheduling |
| Effect | All involved processes stop and wait forever | Some processes never get CPU or resources |
| Resource Allocation | Mutual hold and wait of resources | Resource denied repeatedly to some processes |
| Detection | Can be detected by resource allocation graphs | Harder to detect, depends on scheduling policy |
| Resolution | Requires resource preemption or process termination | Priority adjustment or fair scheduling |
| Example | Two processes each holding a resource the other needs | Low priority process never gets CPU time |
Key Differences
Deadlock is a situation where a group of processes are each waiting for resources held by the others, creating a cycle that stops all involved processes from proceeding. This is a system-wide problem causing a complete halt in progress for those processes.
In contrast, starvation happens when a process waits indefinitely because other processes with higher priority keep getting the resources first. Unlike deadlock, starvation affects individual processes rather than a group, and the system as a whole may still be running.
Deadlock requires a circular wait condition and mutual resource holding, while starvation results from unfair scheduling or priority policies. Deadlock can be detected and resolved by analyzing resource allocation, but starvation often needs changes in scheduling to ensure fairness.
Deadlock Code Example
This example shows a simple deadlock scenario using two threads trying to lock two resources in opposite order.
import threading import time lock1 = threading.Lock() lock2 = threading.Lock() def thread1(): with lock1: time.sleep(0.1) with lock2: print("Thread 1 acquired both locks") def thread2(): with lock2: time.sleep(0.1) with lock1: print("Thread 2 acquired both locks") t1 = threading.Thread(target=thread1) t2 = threading.Thread(target=thread2) t1.start() t2.start() t1.join() t2.join()
Starvation Equivalent
This example simulates starvation by using thread priorities where a low priority thread never gets CPU time because higher priority threads keep running.
import threading import time class StarvationThread(threading.Thread): def __init__(self, name, priority): super().__init__() self.name = name self.priority = priority self.running = True def run(self): count = 0 while self.running and count < 5: if self.priority == 'high': print(f"{self.name} running") time.sleep(0.1) count += 1 else: # Low priority thread gets less chance time.sleep(0.3) high1 = StarvationThread('HighPriority1', 'high') high2 = StarvationThread('HighPriority2', 'high') low = StarvationThread('LowPriority', 'low') high1.start() high2.start() low.start() high1.join() high2.join() low.running = False low.join()
When to Use Which
Choose deadlock prevention and detection techniques when you want to avoid system-wide halts caused by processes waiting on each other indefinitely. This is critical in systems where resource sharing is complex and must be carefully managed.
Choose starvation avoidance by implementing fair scheduling and priority adjustments when you want to ensure all processes get a chance to run, especially in priority-based systems where some tasks might otherwise be ignored.