BCS401 Operating System Semester IV · AY 2025-26 onward
Unit 3 · CPU Scheduling, Threads & Deadlocks

Lecture 9: Deadlocks: prevention, avoidance, detection & recovery

Learning outcomes

  • Describe deadlock conditions and compare deadlock prevention, avoidance, detection and recovery techniques.
Lecture Notes

Main content

Deadlock Avoidance, Detection and Recovery

Learning Focus

Understand how operating systems avoid deadlocks using safe-state checking, how they detect deadlocks after they occur, and how they recover using termination or resource preemption.


1) Where This Lecture Fits

Once deadlock has been characterized and its necessary conditions are understood, the next question is practical: what should the operating system do about it? There are three major approaches:

  • Prevention: break one of the necessary conditions.
  • Avoidance: allow resource requests only if the system remains safe.
  • Detection and Recovery: allow deadlocks to occur, detect them, then recover.

This lecture focuses on the last two: avoidance and detection with recovery.

2) Deadlock Avoidance

Deadlock avoidance is less rigid than prevention. It does not stop resource sharing completely. Instead, it checks each resource request carefully and grants it only if the system will remain in a safe state.

2.1 Safe State

A system is in a safe state if there exists at least one safe sequence of all processes such that each process can obtain its remaining resources, finish, and release its resources for the next process.

Safe State

  • At least one safe sequence exists
  • Deadlock will not occur if the sequence is followed
  • Resource grant is acceptable

Unsafe State

  • No safe sequence is currently visible
  • Deadlock has not necessarily happened yet
  • But deadlock may occur later

So the key idea is: avoidance refuses requests that would move the system from safe to unsafe.

2.2 Avoidance with Single Instance per Resource Type

If each resource type has only one instance, the Resource Allocation Graph can be extended using a claim edge. A claim edge shows that a process may request that resource in the future.

When a request is made, the operating system checks whether granting the request would create a cycle. If granting it creates a cycle, the request is delayed.

3) Banker’s Algorithm

For systems with multiple instances of each resource type, the classical avoidance method is the Banker’s Algorithm. The OS behaves like a cautious banker: it grants a request only if the resulting state remains safe.

3.1 Data Structures Used

Structure Meaning
Available[m] Number of available instances of each resource type
Max[n][m] Maximum demand of each process
Allocation[n][m] Resources of each type currently allocated to each process
Need[n][m] Remaining resource need of each process

The basic formula is:

Need = Max - Allocation

3.2 Safety Algorithm

The safety algorithm checks whether the current state is safe.

  1. Set Work = Available
  2. Set Finish[i] = false for all processes
  3. Find a process Pi such that:
    • Finish[i] == false
    • Need[i] <= Work
  4. If found, pretend that process finishes:
    Work = Work + Allocation[i]
    Finish[i] = true
  5. Repeat until all processes finish or no suitable process can be found

If all Finish[i] values become true, the system is safe. Otherwise, the state is unsafe.

3.3 Resource Request Algorithm

When process Pi requests Request[i], the OS performs these checks:

  1. If Request[i] <= Need[i], continue. Otherwise, the process has exceeded its maximum claim.
  2. If Request[i] <= Available, continue. Otherwise, the process must wait.
  3. Pretend to allocate:
    Available = Available - Request[i]
    Allocation[i] = Allocation[i] + Request[i]
    Need[i] = Need[i] - Request[i]
  4. Run the safety algorithm.
  5. If the state is safe, grant the request permanently. If unsafe, roll back the pretend allocation and make the process wait.

3.4 Merits and Limitations of Avoidance

Merits

  • More flexible than prevention
  • Better resource utilization
  • Stops unsafe states before deadlock occurs

Limitations

  • Maximum resource needs must be known in advance
  • Repeated safety checking adds overhead
  • Often impractical in general-purpose systems

4) Deadlock Detection

In deadlock detection, the operating system does not try to prevent or avoid deadlocks during normal execution. It simply allows the system to operate, then checks periodically whether a deadlock has occurred.

This approach is useful when:

  • deadlock is expected to be rare, and
  • the overhead of prevention or avoidance is considered too high.

4.1 Detection with Single Instance of Each Resource Type

For single-instance resources, a Wait-For Graph is used.

  • Nodes represent processes only.
  • An edge Pi → Pj means Pi is waiting for a resource held by Pj.

Rule: If the wait-for graph contains a cycle, then a deadlock exists.

4.2 Detection with Several Instances of Resource Types

For multiple instances, the OS uses a matrix-based detection algorithm. The main data structures are:

  • Available
  • Allocation
  • Request

Detection steps:

  1. Set Work = Available
  2. If Allocation[i] == 0, set Finish[i] = true, else false
  3. Find a process Pi such that:
    • Finish[i] == false
    • Request[i] <= Work
  4. If found:
    Work = Work + Allocation[i]
    Finish[i] = true
  5. Repeat
  6. If some Finish[i] values remain false, those processes are deadlocked.

4.3 When Should Detection Run?

Detection may be run:

  • whenever a request cannot be granted immediately,
  • periodically after a fixed interval,
  • when CPU utilization drops suspiciously, or
  • on demand by an administrator.

Frequent detection finds deadlocks earlier but adds overhead. Infrequent detection reduces overhead but may allow the deadlock to affect more processes.

5) Recovery from Deadlock

Once deadlock is detected, the system must recover. The two standard recovery strategies are:

  • process termination
  • resource preemption

5.1 Process Termination

There are two main approaches:

  1. Abort all deadlocked processes — simple, but very costly.
  2. Abort one process at a time until the cycle is broken.

When aborting one process at a time, the OS must choose a victim carefully. Victim-selection factors include:

  • process priority
  • amount of computation already done
  • amount of computation still needed
  • number and type of resources held
  • number of other processes that may also need to be aborted
  • whether the process is interactive or batch

5.2 Resource Preemption

Instead of killing processes, the OS may take resources away from one process and give them to another. This sounds elegant, but it is not easy in practice.

Three main issues arise:

  • Selecting a victim: choose which process will lose its resources.
  • Rollback: the victim process may need to return to a safe checkpoint and restart later.
  • Starvation: the same process may be selected again and again as victim.

Resource preemption is difficult because many resources are not safely preemptable. Taking away a printer or an in-progress I/O device is not the same as taking away CPU time.

6) Quick Comparison

Method Main Idea Deadlock Possible? Overhead Resource Utilization
Prevention Break one necessary condition No Medium Often poor
Avoidance Grant requests only if safe No High Better than prevention
Detection Allow deadlocks, then find them Yes, then recover Variable Usually higher
Ignore Do nothing special Yes Very low High, but risky

7) Key Exam Points

  • Avoidance is based on safe-state checking.
  • Banker’s Algorithm is the standard avoidance method for multiple resource instances.
  • Detection does not stop deadlock in advance; it finds it later.
  • Wait-for graph is used for single-instance detection.
  • Matrix-based detection is used for multiple-instance detection.
  • Recovery is done by process termination or resource preemption.

Worked Example

Worked Example: Safe-State Check Using Banker’s Algorithm

Consider a system with five processes P0 to P4 and three resource types A, B, C. Let the currently available resources be:

Available = [3, 3, 2]

Let the current allocation and maximum need be:

Process Allocation (A B C) Max (A B C)
P00 1 07 5 3
P12 0 03 2 2
P23 0 29 0 2
P32 1 12 2 2
P40 0 24 3 3

First compute:

Need = Max - Allocation
Process Need (A B C)
P07 4 3
P11 2 2
P26 0 0
P30 1 1
P44 3 1

Step 1: Start with Work = Available

Work = [3, 3, 2]

Step 2: Search for a process whose Need ≤ Work

  • P1: Need = [1,2,2] ≤ [3,3,2] ✓

So pretend P1 finishes and releases its allocation:

Work = Work + Allocation[P1]
Work = [3,3,2] + [2,0,0] = [5,3,2]

Step 3: Repeat

  • P3: Need = [0,1,1] ≤ [5,3,2] ✓
Work = [5,3,2] + [2,1,1] = [7,4,3]
  • P4: Need = [4,3,1] ≤ [7,4,3] ✓
Work = [7,4,3] + [0,0,2] = [7,4,5]
  • P0: Need = [7,4,3] ≤ [7,4,5] ✓
Work = [7,4,5] + [0,1,0] = [7,5,5]
  • P2: Need = [6,0,0] ≤ [7,5,5] ✓
Work = [7,5,5] + [3,0,2] = [10,5,7]

Safe Sequence

<P1, P3, P4, P0, P2>

Conclusion: Because all processes can finish in some order, the system is in a safe state. Therefore, the current allocation is acceptable.

Observation: This example shows why Banker’s Algorithm is called an avoidance method. It does not wait for a deadlock to happen. It checks whether the system will remain safe before approving or rejecting a request.