Deadlock: conditions and resource allocation graphs
What a deadlock is, the four necessary conditions (mutual exclusion, hold and wait, no preemption, circular wait), resource allocation graphs and when a cycle means deadlock, the four ways of handling deadlock, prevention by breaking each condition, and the minimum number of resources that makes deadlock impossible.
Why it exists
Processes compete for resources: printers, files, locks, memory buffers, semaphores. A process requests a resource, uses it and releases it. If the resource is not free, the process waits. Waiting is normal; but waiting can become permanent. Two processes each hold something the other needs and each waits for the other: neither can ever continue. This is deadlock. It is not about slow processes; it is a state from which, without outside intervention, no process in the group can ever proceed. GATE asks you to identify the conditions that make it possible, to read deadlocks from resource allocation graphs, to tell which strategy breaks which condition, and to compute the minimum number of resource units for which deadlock cannot occur.
Prerequisites
You need the process and its waiting state from the process model; semaphores and locks are the usual resources, as in semaphores and the classic problems.
Precise definitions
Resource. Anything a process must hold exclusively for a while: a device, a file, a lock, a semaphore, a memory region. A resource type may have several identical instances (for example 3 printers). A process uses a resource in three steps: request (wait if no instance is free), use, release.
Deadlock. A set of processes is deadlocked if every process in the set is waiting for an event (here, the release of a resource) that only another process in the set can cause. None can proceed, so none will ever release anything.
The four necessary conditions (Coffman conditions). A deadlock can occur only if all four hold at the same time:
- Mutual exclusion: at least one resource is held in a non-sharable mode (only one process at a time can use it).
- Hold and wait: a process holds at least one resource while waiting to acquire additional resources held by others.
- No preemption: a resource can be released only voluntarily by the process holding it; it cannot be taken away.
- Circular wait: there is a set of waiting processes such that waits for a resource held by , for one held by , ..., and for one held by .
The four conditions are necessary. Together they are not always sufficient (see the graph with several instances below).
Resource allocation graph (RAG). A directed graph with a node for each process (drawn as a circle) and each resource type (a box with one dot per instance).
- A request edge : process has requested an instance of and is waiting.
- An assignment edge : an instance of is held by .
Facts, for a graph in which no process requests more instances than exist:
- If the graph has no cycle, there is no deadlock.
- If every resource type has one instance, then a cycle means deadlock (and deadlock means a cycle).
- If some resource types have several instances, a cycle is necessary but not sufficient: there may be a cycle and no deadlock (when an instance in the cycle is held by a process that is not waiting and will release it). The deadlock test is then the reduction algorithm: repeatedly find a process whose outstanding requests can all be satisfied by the free instances, let it finish and release all it holds; the processes that can never finish are the deadlocked ones.
Four ways to handle deadlock.
- Ignore it (the "ostrich algorithm"): assume it is rare and let the operator reboot. Used by most general-purpose systems for most resources.
- Prevention: make sure at least one of the four conditions can never hold.
- Avoidance: let the system decide at each request whether granting it could lead to deadlock, using advance information about the maximum needs (Banker's algorithm).
- Detection and recovery: allow deadlocks, detect them (cycle search or the reduction algorithm) and recover by terminating processes or preempting resources (detection and recovery).
Prevention, condition by condition.
| Condition | How to deny it | Cost |
|---|---|---|
| Mutual exclusion | make resources sharable (read-only files) or spool (a printer daemon) | impossible for some resources (a writable file, a lock) |
| Hold and wait | a process must request all its resources at once, or may request only when it holds none | low resource use; a process may wait a long time; starvation |
| No preemption | if a request cannot be granted, the process releases all it holds and retries; or take resources from waiting processes | only works for resources whose state can be saved and restored (CPU registers, memory), not printers |
| Circular wait | give each resource type a number and let a process request resources only in increasing order of numbers | the programmer must follow the order; resources must be requested earlier than needed |
Why ordering works: a cycle would require, going round it, a resource number that is both greater than and less than itself, which is impossible.
Deadlock is not starvation. In starvation one process waits indefinitely but the system as a whole progresses (for example SJF). In deadlock every process in the set is blocked. In livelock the processes keep running and changing state but make no progress.
Resources needed so that deadlock cannot happen. Suppose processes share identical units of one resource type, process needs at most units in all, requests one unit at a time, and holds everything until it has all its units. Deadlock is impossible if and only if
(If is smaller, every process can be holding one unit fewer than its maximum, using up all units, and all wait.) When every process needs units: .
How it works
The animations are resource allocation graphs built event by event; the cycle and the deadlock are computed by script at each step. First the standard deadlock: two processes, two single-instance resources, requested in opposite orders. The last request closes the cycle and, since each resource has one instance, it is a deadlock.
A deadlock: P1 and P2 each hold what the other wants: start
Graph analysed by script, not typedDashed arrow: a request (process to resource). Solid arrow: an assignment (resource to the process that holds an instance). Filled dot: an instance in use.
Step 0
Two processes and two resources with ONE instance each. The graph starts empty. Step through the requests: assignment edges point from a resource to its holder, request edges from a waiting process to the resource.
Now a cycle that is not a deadlock. R1 has two instances. After the last request the graph has a cycle through P1, R1, P3 and R2, but R1's other instance is held by P2, which is not waiting for anything. When P2 finishes it releases R1, P1 gets it, and the cycle disappears.
A cycle without a deadlock: the resource has two instances: start
Graph analysed by script, not typedDashed arrow: a request (process to resource). Solid arrow: an assignment (resource to the process that holds an instance). Filled dot: an instance in use.
Step 0
R1 has TWO instances and R2 has one. With several instances a cycle is necessary for deadlock but not sufficient. Step through the requests and watch the cycle appear and the deadlock check stay clear.
And prevention by ordering: both processes request R1 before R2. Whoever gets R1 first can go on to take R2 and finish; the other simply waits. No cycle can ever form.
Both processes ask for R1 first: no cycle can form: start
Graph analysed by script, not typedDashed arrow: a request (process to resource). Solid arrow: an assignment (resource to the process that holds an instance). Filled dot: an instance in use.
Step 0
The same two processes and resources, but now BOTH acquire R1 before R2 (a fixed global order of acquisition). Whichever gets R1 first can go on to take R2 and finish.
Worked examples
EX 1Reading the first graph
EasyAfter the last step of the first animation the graph has the edges (assignment), (assignment), (request) and (request): the cycle . Check the four conditions: mutual exclusion (each resource is held by one process), hold and wait (each process holds one and waits for the other), no preemption (nobody can take a resource away), circular wait (the cycle). Each resource has one instance, so the cycle is a deadlock. Break any one condition (for example let P2 request R1 before R2, an ordering) and it cannot happen.
EX 2A cycle that is not a deadlock
MediumR1 has 2 instances, R2 has 1. P1 holds R2 and requests R1. P2 and P3 hold one instance of R1 each, and P3 also requests R2. The cycle is . Apply the reduction: no instance is free. P2 is not waiting for anything, so it can finish and release its instance of R1. Then P1's request for R1 can be granted, P1 finishes and releases R2, which P3 then obtains. Everybody finishes: no deadlock. A cycle in a graph with a multi-instance resource must be checked by this reduction, not assumed to be a deadlock. (In a random trial of graphs, about 1 in 17 had a cycle without a deadlock.)
EX 3The minimum number of resources
MediumThree processes each need at most 2 units of a resource and request one unit at a time. The worst case is that each holds one unit; with 3 units, all three are holding one and waiting for a second: deadlock. With 4 units one process can always get its second unit and finish. So the minimum is . A program searches every reachable state to confirm the formula:
#include <stdio.h>
#include <string.h>
/* n processes, each needing up to k units of one resource type, asking for one unit at a time and releasing everything when it holds k.
For R units in all, explore EVERY reachable state and report whether a deadlock (unfinished processes, none able to proceed) is reachable. */
static int n, k, R;
static unsigned char seen[8192];
static int encode(const int *held, int freeu) {
int code = 0;
for (int i = 0; i < n; i++) code = code * (k + 1) + held[i];
return code * 64 + freeu;
}
static int deadlock_reachable(const int *held, int freeu) {
int code = encode(held, freeu);
if (seen[code]) return 0;
seen[code] = 1;
int moved = 0, unfinished = 0;
for (int i = 0; i < n; i++) {
if (held[i] == k) continue; /* finished: its units were returned when it reached k */
unfinished = 1;
if (freeu == 0) continue;
moved = 1;
int next[8], f = freeu - 1;
memcpy(next, held, sizeof(int) * (size_t)n);
next[i]++;
if (next[i] == k) f += k; /* it now holds all it needs, finishes and releases */
if (deadlock_reachable(next, f)) return 1;
}
return unfinished && !moved;
}
int main(void) {
for (n = 1; n <= 4; n++) {
for (k = 1; k <= 3; k++) {
int found = -1;
for (R = 1; R <= n * k + 1 && found < 0; R++) {
int held[8] = {0};
memset(seen, 0, sizeof seen);
if (!deadlock_reachable(held, R)) found = R;
}
printf("%d processes, each needs up to %d units: deadlock is impossible from %2d units up; formula n(k-1)+1 = %2d\n", n, k, found, n * (k - 1) + 1);
}
}
return 0;
}1 processes, each needs up to 1 units: deadlock is impossible from 1 units up; formula n(k-1)+1 = 1
1 processes, each needs up to 2 units: deadlock is impossible from 2 units up; formula n(k-1)+1 = 2
1 processes, each needs up to 3 units: deadlock is impossible from 3 units up; formula n(k-1)+1 = 3
2 processes, each needs up to 1 units: deadlock is impossible from 1 units up; formula n(k-1)+1 = 1
2 processes, each needs up to 2 units: deadlock is impossible from 3 units up; formula n(k-1)+1 = 3
2 processes, each needs up to 3 units: deadlock is impossible from 5 units up; formula n(k-1)+1 = 5
3 processes, each needs up to 1 units: deadlock is impossible from 1 units up; formula n(k-1)+1 = 1
3 processes, each needs up to 2 units: deadlock is impossible from 4 units up; formula n(k-1)+1 = 4
3 processes, each needs up to 3 units: deadlock is impossible from 7 units up; formula n(k-1)+1 = 7
4 processes, each needs up to 1 units: deadlock is impossible from 1 units up; formula n(k-1)+1 = 1
4 processes, each needs up to 2 units: deadlock is impossible from 5 units up; formula n(k-1)+1 = 5
4 processes, each needs up to 3 units: deadlock is impossible from 9 units up; formula n(k-1)+1 = 9Reading it. The smallest number of units for which deadlock cannot be reached always equals . With different maximum needs it is : for needs 2, 3 and 4 it is , and for 3, 4 and 5 it is 10 (checked by the same search).
EX 4Which condition does each strategy break?
MediumRequest all resources at the start: breaks hold and wait (a process never waits while holding). If a request fails, release everything and try again: breaks no preemption. Number the resources and request in increasing order: breaks circular wait. Spool the printer so that many processes can "print" at once: attacks mutual exclusion (the spooler is the only process using the physical printer). A question usually lists a method and asks which of the four conditions it denies, or which condition cannot practically be denied (mutual exclusion, for resources that really are non-sharable).
EX 5Why does the ordering rule work, and what does it cost?
GATE levelAssign numbers: tape drive 1, disk 2, printer 3. Rule: a process holding resources of number may only request resources with numbers greater than . A deadlock needs a cycle of waits holds and waits for held by which waits for ... and waits for . By the rule , impossible. A search over 600 random programs (each process acquiring a random subset of up to four resources in increasing order) found no reachable deadlock, while about 40% of the same programs with the acquisition orders shuffled could deadlock. The cost: a process that needs the printer and then the tape must take the tape first and hold it longer than necessary, which lowers utilization.
Cheat box
Cheat box
- Deadlock needs all four: mutual exclusion, hold and wait, no preemption, circular wait.
- RAG: request edge , assignment edge . No cycle no deadlock. One instance each: cycle deadlock. Several instances: cycle is necessary, not sufficient; use the reduction algorithm.
- Handling: ignore, prevent, avoid, detect and recover.
- Prevention: all-at-once requests (hold and wait), preempt (no preemption), ordered requests (circular wait); mutual exclusion cannot usually be denied.
- Deadlock-free if ; for processes each needing : .
- Starvation is not deadlock.
Traps and GATE patterns
Connections
Builds on
Unlocks
Across subjects
No cross-subject links yet.
The resources are often semaphores: two processes waiting on two semaphores in opposite orders are exactly the cycle above, and the dining philosophers are a circular wait. Granting a request only when it keeps the system safe is deadlock avoidance; finding deadlocks after the fact and recovering is detection and recovery.
PYQs
9 previous year questions from your book. I re-solved each one myself (3 by running or simulating, 6 by reasoning only); the book's key is shown next to my answer. All PYQs
Consider a computer system with multiple shared
resource types, with one instance per resource type.
Each instance can be owned by only one process at
a time. Owning and freeing of resources are done
by holding a global lock (L). The following scheme
is used to own a resource instance:
function OWNRESOURCE(Resource R)
Acquire lock L // a global lock
if R is available then
Acquire R
Release lock L
else
if R is owned by another process P then
Terminate P, after releasing all resources
owned by P
Acquire R
Restart P
Release lock L
end if
end if
end if
end function
Which of the following choice(s) about the above
scheme is/are correct?- (a)The scheme violates the mutual exclusion property.
- (b)The scheme ensures that deadlocks will not occur.
- (c)The scheme may lead to starvation.
- (d)The scheme may lead to live-lock.
With respect to deadlocks in an operating system, which of the following statements is/are FALSE?
- (a)Banker's algorithm is used to prevent deadlocks
- (b)Deadlock formation can be prevented by ensuring that the hold and wait condition is not allowed
- (c)An assignment edge in a resource allocation graph is marked from a process to a resource
- (d)A safe state guarantees that all processes can finish without formation of a deadlock
P = {P1, P2, P3, P4} consists of all active processes
in an operating system. R = {R1, R2, R3, R4} consists
of single instances of distinct types of resources in the
system.
The resource allocation graph has the following
assignment and claim edges.
Assignment edges: R1 → P1, R2 → P2, R3 → P3, R4
→ P4 (the assignment edge R1 → P1 means resource
R1 is assigned to process P1 , and so on for others)
Claim edges: P1 → R2, P2 → R3, P3 → R1, P2 →
R4, P4 → R2 (the claim edge P1 → R2 means process
P1 is waiting for resource R2 , and so on for others)
Which
of
the
following
statement(s)
is/are
CORRECT?- (a)Aborting P1 makes the system deadlock free.
- (b)Aborting P3 makes the system deadlock free
- (c)Aborting P2 makes the system deadlock free
- (d)Aborting P1 and P4 makes the system deadlock free.
Which of the following statements is/are TRUE with respect to deadlocks?
- (a)The circular wait is a necessary condition for the formation of deadlock
- (b)In a system where each resource has more than one instance, a cycle in its wait-for graph indicates the presence of a deadlock.
- (c)If the current allocation of resources to processes leads the system to an unsafe state, then deadlock will necessarily occur.
- (d)In the resource-allocation graph of a system, if every edge is an assignment edge, then the system is not in a deadlock state. OPERATING SYSTEMS
A multithreaded program P executes with x number of threads and used y number of locks for ensuring mutual exclusion while operating on shared memory locations. All locks in the program are non-reentrant, i.e., if a thread holds a lock l, then it cannot re-acquire lock l without releasing it. If a thread is unable to acquire a lock, it blocks until the lock becomes available. The minimum value of x and the minimum value of y together for which execution of P can result in a deadlock are:
- (a)x = 1, y = 2
- (b)x = 2, y = 1
- (c)x = 2, y = 2
- (d)x = 1, y = 1 OPERATING SYSTEMS
Consider the following policies for preventing deadlock in a system with mutually exclusive resources. I. Processes should acquire all their resources at the beginning of execution. If any resource is not available, all resources acquired so far are released. II. The resources are numbered uniquely, and processes are allowed to request for resources only in increasing resource numbers. III. The resources are numbered uniquely, and processes are allowed to request for resources only in decreasing resource numbers. IV. The resources are numbered uniquely. A process is allowed to request only for a resource with resource number larger than its currently held resources. Which of the above policies can be used for preventing deadlock?
- (a)Any one of I and III but not II or IV
- (b)Any one of I, III, and IV but not II
- (c)Any one of II and III but not I or IV
- (d)Any one of I, II, III, and IV
Three concurrent processes X, Y, and Z execute three different code segments that access and update certain shared variables. Process X executes the P operation (i.e., wait) on semaphores a, b, and c; process Y executes the P operation on semaphores b, c, and d; process Z executes the P operation on semaphores c, d, and a before entering the respective code segments. After completing the execution of its code segment, each process invokes the V operation (i.e., signal) on its three semaphores. All semaphores are binary semaphores initialized to one. Which one of the following represents a deadlock-free order of invoking the P operations by the processes?
- (a)X: P(a) P(b) P(c)Y: P(b) P(c) P(d) Z: P(c) P(d) P(a)
- (b)X: P(b) P(a) P(c) Y: P(b) P(c) P(d) Z: P(a) P(c) P(d)
- (c)X: P(b) P(a) P(c) Y: P(c) P(b) P(d) Z: P(a) P(c) P(d)
- (d)X: P(a) P(b) P(c) Y: P(c) P(b) P(d) Z: P(c) P(d) P(a)
A system has n resources R0...,Rn-1, and k processes
P0....Pk-1. The implementation of the resource
request logic of each process Pi is as follows:
if (i % 2 == 0) {
if (i < n) request Ri
if (i+2 < n) request Ri+2
}
else {
if (i < n) request Rn-i
if (i+2 < n) request Rn-i-2
}
In which one of the following situations is a deadlock
possible?- (a)n = 40, k = 26
- (b)n = 21, k = 12
- (c)n = 20, k = 10
- (d)n = 41, k = 19
Which of the following is NOT true of deadlock prevention and deadlock avoidance schemes?
- (a)In deadlock prevention, the request for resources is always granted if the resulting state is safe
- (b)In deadlock avoidance, the request for resources is always granted if the resulting state is safe
- (c)Deadlock avoidance is less restrictive than deadlock prevention
- (d)Deadlock avoidance requires knowledge of resource requirements a priori
Self-check
Question 1
Four processes each need at most 3 units of one resource type, one unit at a time. What is the least number of units that makes deadlock impossible?
Show answerHide
.
Question 2
A resource allocation graph contains a cycle, and every resource in the cycle has one instance. Is there a deadlock?
Show answerHide
Yes. With single instances a cycle is a deadlock.
Question 3
Which Coffman condition does "resources are numbered and requested only in increasing order" deny?
Show answerHide
Circular wait.
Question 4
R1 has two instances, held by P2 and P3. P1 waits for R1. P3 waits for R2, which P1 holds. P2 waits for nothing. Deadlock?
Show answerHide
No. P2 can finish and release an instance of R1; P1 then gets it, finishes and releases R2, and P3 finishes. There is a cycle but no deadlock.
Revision card
One-screen revision
- Four conditions: mutual exclusion, hold and wait, no preemption, circular wait.
- RAG: no cycle, no deadlock; single instance: cycle = deadlock; multiple: reduction algorithm.
- Prevention: all at once, preempt, ordered requests. Avoidance: Banker's. Detection: reduction.
- Minimum units for no deadlock: .
References
- ·Silberschatz, Galvin, Gagne, Operating System Concepts, Chapter 8 Deadlocks (system model, deadlock characterization, methods for handling deadlocks, deadlock prevention)
- ·Tanenbaum and Bos, Modern Operating Systems, Chapter 6 Deadlocks (resources, introduction to deadlocks, the ostrich algorithm, deadlock prevention)
- ·Stallings, Operating Systems: Internals and Design Principles, Chapter 6 Concurrency: Deadlock and Starvation
Verification
The graph results are checked on thousands of random resource allocation graphs in scripts/enum-checks/os_deadlock.py, with deadlocks found by the reduction algorithm and cycles by reachability: a deadlock always contains a cycle; with single-instance resources a cycle is exactly a deadlock; with several instances cycles without deadlock occur (268 of 4589 random graphs). The animations are rechecked by an independent TypeScript analysis of every step's edges (tests/os-deadlock-traces.test.ts). The claim that a fixed global order of acquisition makes deadlock impossible, and that unordered programs can deadlock, is checked by exhaustively exploring the reachable states of 600 random programs. The minimum number of resources n(k-1)+1 is found by exhaustive state search in Python and in the C program on this page (npm run verify:c), for up to 4 processes needing up to 3 units, and the general form sum(max_i - 1) + 1 on random demands. The model: resources are acquired one unit at a time, held until the process has all it needs, then released; real systems have more complicated resource use. Textbook chapter titles are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand. No defect found. Status raised to self-checked; verified needs a textbook or human check.
last verified: never
My notes (saved in this browser)