0% found this document useful (0 votes)
80 views

CH 7

The document discusses methods for preventing deadlocks in operating systems. It describes the four conditions required for deadlock and approaches like mutual exclusion, holding and waiting, preemption, and limiting resource allocation to prevent deadlocks from occurring.

Uploaded by

Ali Nasir
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
80 views

CH 7

The document discusses methods for preventing deadlocks in operating systems. It describes the four conditions required for deadlock and approaches like mutual exclusion, holding and waiting, preemption, and limiting resource allocation to prevent deadlocks from occurring.

Uploaded by

Ali Nasir
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 50

Chapter 7: Deadlocks

Operating System Concepts 9th Edition Silberschatz, Galvin and Gagne 2013, modified by Dmitri V. Kalashnikov and Venkatasubramanian
Chapter 7: Deadlocks
System Model
Deadlock Characterization
Methods for Handling Deadlocks
Deadlock Prevention
Deadlock Avoidance
Deadlock Detection
Recovery from Deadlock

7.2
Chapter Objectives

To develop a description of deadlocks, which prevent sets of


concurrent processes from completing their tasks
To present a number of different methods for preventing or
avoiding deadlocks in a computer system

7.3
Deadlock
Recall from Chapter 5
Deadlock two or more processes are waiting indefinitely for an
event that can be caused by only one of the waiting processes
Example: Let S and Q be two semaphores initialized to 1
P0 P1
wait(S); wait(Q);
wait(Q); wait(S);
... ...
signal(S); signal(Q);
signal(Q); signal(S);

7.4
System Model
System consists of resources
Resource types R1, R2, . . ., Rm
CPU cycles, files, memory space, I/O devices, etc
Each resource type Ri has Wi instances.
Type: CPU
2 instances - CPU1, CPU2
Type: Printer
3 instances - printer1, printer2, printer3

7.5
System Model
Each process utilizes a resource as follows:
Request resource
A process can request a resource of a given type
E.g., I request any printer
System will then assign a instance of that resource to the process
E.g., some printer will be assigned to it
If cannot be granted immediately, the process must wait until it can get it
Use resource
Operate on the resource, e.g. print on the printer
Release resource
Mutexes and Semaphores
Special case:
Each mutex or semaphor is treated as a separate resource type
Because a process would want to get not just any lock among a group of locks, but a
specific lock that guards a specific shared data type
e.g., lock that guards a specific queue

7.6
Deadlock Characterization
Deadlock can arise if 4 conditions hold simultaneously:
Mutual exclusion: only one process at a time can use a resource
Hold and wait: a process holding at least one resource is waiting to
acquire additional resources held by other processes
No preemption: a resource can be released only voluntarily by the
process holding it, after that process has completed its task
Circular wait: there exists a set {P0, P1, , Pn} of waiting processes
such that
P0 is waiting for a resource that is held by P1, and so on:
P0 P1 P2 Pn1 Pn P0
Notice: Circular wait implies Hold and Wait
Why then not test for only the Circular wait?
Because, computationally, Hold and wait can be tested much
more efficiently than Circular wait
Some algorithms we consider only need to check H&W

7.7
Deadlock with Mutex Locks
Deadlocks can occur via system calls, locking, etc.
Trivial example
Mutexes A, B unlocked initially
Process P1: wait(A); wait(B);
Process P2: wait(B); wait(A);

7.8
Deadlock Example
/* thread one runs in this function */
void *do_work_one(void *param)
{

pthread_mutex_lock(&first_mutex);
pthread_mutex_lock(&second_mutex);
/** * Do some work */
pthread_mutex_unlock(&second_mutex);
pthread_mutex_unlock(&first_mutex);
pthread_exit(0);
}
/* thread two runs in this function */
void *do_work_two(void *param)
{

pthread_mutex_lock(&second_mutex);
pthread_mutex_lock(&first_mutex);
/** * Do some work */
pthread_mutex_unlock(&first_mutex);
pthread_mutex_unlock(&second_mutex);
pthread_exit(0);
}

7.9
Resource-Allocation Graph
Resource-Allocation Graph
Useful tool to describe and analyze deadlocks
Set of vertices V
Set of edges E
V is partitioned into two types:
P = {P1, P2, , Pn}, the set of all the processes in the system
R = {R1, R2, , Rm}, the set of all resource types in the system

request edge directed edge Pi Rj


Means Pi has requested (an instance of) Rj and now is waiting for it

assignment edge directed edge Rj Pi


Means an instance of Rj has been assigned to Pi

7.10
Pictorial Representation
Process

Resource Type (with 4 dots for 4 instances in this specific example)

Pi requests instance of Rj

Pi
Rj
Pi is holding an instance of Rj

Pi
Rj

7.11
Example of a Resource Allocation Graph

7.12
Basic facts
Consider Resource-Allocation Graph

Case 1: Each resource type has only 1 instance


A cycle in the graph is a necessary and sufficient condition for a
deadlock
That is: graph has a cycle a deadlock

Case 2: A resource type can have multiple instances


A cycle in the graph is a necessary (but not sufficient) condition
for a deadlock, that is:
If graph has no cycles, then no process is deadlocked
If graph has a cycle, may (or may not) be deadlocked

7.13
Two Minimal Cycles and P1 P2 P3 are Deadlocked

7.14
A Cycle But No Deadlock

P4 might release its instance of R2


That instance will then be allocated to P3
Edge P3 R2 will become R2 P3
Hence, the cycle will break
7.15
Methods for Handling Deadlocks
Three ways to handle deadlocks:
1. Ensure that the system will never enter a deadlock state:
Deadlock prevention
Deadlock avoidance
2. Allow the system to enter a deadlock state and then recover
3. Ignore the problem and pretend that deadlocks never occur in the system
Used by most operating systems, including UNIX
One reason: Handling deadlocks can be computationally expensive

7.16
Deadlock Prevention
Key idea: Restrain the ways request for resources can be made
Recall, all 4 necessary conditions must occur for a deadlock to happen
1. Mutual Exclusion
2. Hold and Wait
3. No preemption
4. Circular Wait
If we ensure at least one condition is not met, we prevent a deadlock

7.17
Deadlock Prevention: Mutual
Exclusion
#1 Mutual Exclusion: only one process at a time can use a resource
Solution:
Mutual exclusion is not required for sharable resources
Example: Accessing the same files, but only for reading
So do not use mutual exclusion for such cases
However, it must hold for non-sharable resources
Bottom line: Use mutual exclusion only when you really have to

7.18
Deadlock Prevention: Hold and Wait

#2 Hold and Wait: a process holding at least one resource is


waiting to acquire additional resources held by other processes
Idea: must guarantee that whenever a process requests a
resource, it does not hold any other resources
Solutions include:
1. Require process to request and be allocated all its
resources before it begins execution, or
2. Allow process to request resources only when the process
has none allocated to it
Cons: Low resource utilization; starvation possible

7.19
Deadlock Prevention: No Preemption
#3 No Preemption: a resource can be released only voluntarily by the process holding it,
after that process has completed its task

One possible solution (is to implement preemption):


Assume
Process P is holding some resources - (set) R
P then requests another resource r
But r cannot be immediately allocated to P
That is, P must wait for r
Then
All resources R are preempted
That is, they are implicitly released
Resources from R are added to the list of resources for which P is waiting
P will be restarted only when it can regain R , as well as r

7.20
Deadlock Prevention: Circular Wait
#4 Circular Wait: there exists a set {P0, P1, , Pn} of waiting processes such that
P0 is waiting for a resource that is held by P1, and so on
P0 P1 P2 Pn1 Pn P0
One possible solution:
impose a total ordering of all resource types, and
OrderOf(Rj) gives order of Rj
require that each process requests resources in an increasing order of enumeration
Rewrite the code such that this holds
If a process holds a lock for Rj it should not request a lock for any Rk such that
OrderOf(Rk) < OrderOf(Rj)
Example
Order resources A,B,C,D,E as D < E < C < A < B
Assume: Process holds a lock for, say, A and C
Then, the process should not request locks for D or E

7.21
Deadlock Example with Lock Ordering
void transaction(Account from, Account to, double amount)
{
mutex lock1, lock2;
lock1 = get_lock(from); // notice, lock1 is assigned dynamically
lock2 = get_lock(to); // lock2 is assigned dynamically as well
acquire(lock1); // yes, lock1 is always acquired before lock2
acquire(lock2); // but it does not mean order(lock1) < order(lock2)

withdraw(from, amount);
deposit(to, amount);

release(lock2);
release(lock1);
}

Transactions 1 and 2 execute concurrently: (1) transaction(A, B, $25) (2) transaction(B, A, $50)
Deadlock is possible (even though a presumed ordering exists)
Because locks are acquired/assigned dynamically
How to fix it?
dont fix the order to lock1 and then lock2
Instead, order lock1 and lock2 each time: after get_lock() but before acquire()
7.22
Deadlock Avoidance
Idea: Require that the system has some additional a priori information
about how resources will be used
Simplest and most useful model requires that each process
declare the maximum number of resources of each type
that it may need
The deadlock-avoidance algorithm dynamically examines
the resource-allocation state to ensure that there can never
be a circular-wait condition
Resource-allocation state is defined by:
l number of available resources
l number of allocated resources
l maximum resource demands of the processes

7.23
Safe State
The deadlock avoidance algorithm relies on the notion of safe state
A state is safe if the system can allocate resources to each process (up to its
maximum) in some order and still avoid a deadlock.

Formally: System is in safe state only if


There exists a safe sequence (of processes) -- explained shortly
That is, it is possible to order all processes to form a safe sequence

7.24
Safe Sequence
System is in safe state only if there exists a safe sequence

Safe sequence - is a sequence (ordering) <P1, P2, , Pn> of all the


processes in the systems, such that:
for each Pi -- the resources that Pi can still request can be satisfied by:
currently available resources, plus
resources held by all the Pj, with j < i (that is, by P1, P2, , Pi -1)

Intuition behind a safe sequence:


if Pi resource needs are not immediately available
then Pi can wait until P1, P2, , Pi-1 have finished
at that stage Pi will be guaranteed to obtain the needed resources
so Pi can execute, return allocated resources, and terminate

7.25
Basic Facts

If a system is in safe state no deadlocks


If a system is in unsafe state possibility of deadlock
Avoidance ensure that a system will never enter an unsafe state.

Solution: Whenever a process requests a resource that is available:


Decide:
If the resource can be allocated immediately, or
If the process must wait
Request is granted only if it leaves the system in the safe state

7.26
Safe, Unsafe, Deadlock State

7.27
Deadlock Avoidance Algorithms
Deadlock Avoidance algorithms for two cases:

Case 1. Each resource type has exactly 1 instance


Use a (modified) resource-allocation graph
Case 2. A resource type can have multiple instances
Use the bankers algorithm

7.28
Case1: Single instance per resource type
Use the resource allocation graph
Idea: Resources must be claimed a priori in the system
Before they start, all processes declare which exact
resources they may use
Recall that: when only 1 instance per resource type, it holds:
graph contains a cycle deadlock
Solution: the resource allocation graph is augmented
with claim edges
to provide deadlock avoidance

7.29
Edges in the claim graph

Process may request resource

Process has requested resource

Process is assigned resource

7.30
Claim Edges
Claim edge
Pi Rj indicates that process Pj may request resource Rj
It is represented by a dashed line
When a process requests a resource
The claim edge converts to request edge
When the resource is allocated to the process
The request edge converted to an assignment edge
When a resource is released by a process
The assignment edge reconverts to a claim edge

7.31
Resource-Allocation Graph Algorithm

Suppose that process Pi requests a resource Rj


The request can be granted only if converting the request
edge to an assignment edge does not result in the formation
of a cycle in the resource allocation graph

R1 R1

P1 P2 P1 P2

R2 R2
Safe state Unsafe state

7.32
Bankers Algorithm
Now what if Multiple instances of resources per resource type
Use Bankers Algorithm
Each process must a priori claim maximum use
When a process requests an available resource
it may have to wait
When a process gets all its resources
it must return them in a finite amount of time

7.33
Data Structures for the Bankers Algorithm
An example on the next slide
n = number of processes
m = number of resources types
Process Pi, resource type Rj
Available[m]:
vector of length m
Available[j]=k -- means k instances of Rj available
Max[n,m]:
n x m matrix
Max[i,j]=k -- means Pi may request k instances of Rj
Allocation[n,m]:
n x m matrix
Allocation[i,j]=k -- means Pi is currently allocated k instances of Rj
Need[n,m]:
n x m matrix
Need[i,j]=k means Pi may need k more instances of Rj to complete its task
Need[i,j]=Max[i,j] Allocation[i,j]

7.34
Example of Bankers Algorithm
5 processes P0 through P4;
3 resource types:
A (10 instances), B (5instances), and C (7 instances)
Snapshot at time T0:
Allocation MaxAvailable Need
ABC ABC ABC ABC
P0 010 753 332 743
P1 200 322 122
P2 302 902 600
P3 211 222 011
P4 002 433 431

Recall that Need = Max Allocation

7.35
Safety Algorithm
// Conceptually: tries to find a safe sequence by constructing it.
// Adds one process at a time to it
1.Let Work, Finish be vectors of length m and n, respectively. Initialize:
Work=Available; // vector of currently available resources
Finish[i]=false, for i=0,1,,n-1; // Pi is already assigned to the sequence?

2. Find an i such that both: // Find Pi, such that:


(a) Finish[i]=false; // (a) Pi is not yet assigned to the sequence, and
(b) Needi Work; // (b) Pi needs resources than whats currently available
if (no such i exists) goto Step 4;
// Here, Pi is OK to add, and hence added to the working sequence, conceptually

Work = Work + Allocationi; // add to Work resources that Pi already has


// Pi will release them when it finishes
Finish[i] = true; // Pi is assigned to the sequence, so it is done
goto Step 2;

if (Finish[i]==true, for all i) then the system is in a safe state

7.36
Example of Bankers Algorithm
5 processes P0 through P4;
3 resource types:
A (10 instances), B (5instances), and C (7 instances)
Snapshot at time T0:
Allocation MaxAvailable Need
ABC ABC ABC ABC
P0 010 753 332 743
P1 200 322 122
P2 302 902 600
P3 211 222 011
P4 002 433 431

Recall that Need = Max Allocation


The system is in a safe state
Since the sequence < P1, P3, P4, P2, P0> satisfies safety criteria

7.37
Resource-Request Algorithm for Process Pi

Requesti = request vector for process Pi.


Requesti[j]=k means Pi wants k instances of resource type Rj
if (Requesti Needi) goto Step 2.
else signal error, since Pi has exceeded its max claim

if (Requesti Available) goto Step 3.


else Pi must wait, since resources are not available

3. Pretend to allocate requested resources to Pi by modifying the state as follows:


Available = Available Request i;
Allocationi = Allocationi + Requesti;
Needi = Needi Requesti;
If safe the resources are allocated to Pi
If unsafe Pi must wait, and
the old resource-allocation state is restored

7.38
Example: P1 Request (1,0,2)
Check that Request Available (that is, (1,0,2) (3,3,2) true
Available becomes (3,3,2) (1,0,2) = (2,3,0)
Allocation Need Available
ABC ABCABC
P0 010 743 230
P1 302 020
P2 302 600
P3 211 011
P4 002 431

Executing safety algorithm shows that sequence < P1, P3, P4, P0, P2>
satisfies safety requirement

Can request for (3,3,0) by P4 be granted?

Can request for (0,2,0) by P0 be granted?

7.39
Deadlock Detection

If no deadlock-prevention or deadlock-avoidance algorithm is used


Then system can enter a deadlock state

In this environment, the system may provide


Deadlock detection algorithm
Deadlock recovery algorithm

7.40
Single Instance of Each Resource Type

Maintain wait-for graph


A variant of the resource-allocation graph
Nodes are processes
Pi Pj if Pi is waiting for Pj

Periodically invoke an algorithm that searches for a cycle in the graph.


If there is a cycle, there exists a deadlock

An algorithm to detect a cycle in a graph requires an order of n2


operations, where n is the number of vertices in the graph

7.41
Resource-Allocation Graph and Wait-for Graph

Resource-Allocation Graph Corresponding wait-for graph

7.42
Several Instances of a Resource Type
Available[m]:
A vector of length m
indicates the number of available resources of each type
Allocation[n,m]:
An n x m matrix
defines the number of resources of each type currently allocated to
each process
Request[n,m]:
an n x m matrix
indicates the current request of each process.
Request[i][j] = k means process Pi is requesting k more
instances of resource type Rj.

7.43
Detection Algorithm
//Tries to see if there is at least on way to assign resources to processes, otherwise=>deadlock
1.Let Work and Finish be vectors of length m and n, respectively. Initialize:
Work = Available; //Resources currently Available
for (i=0; i<n; i++)
if (Allocationi!=0) Finish[i] = false; // Pi could be deadlocked: check
else Finish[i] = true; // only a process that holds some resources
// can be in a deadlock, otherwise - cannot
2. Find an index i such that both: // Find Pi such that:
(a) Finish[i] == false; // (a) Pi is not done yet, needs to be processed
(b) Requesti Work; // (b) Pi requests resources than available
// optimistic: using Requesti not Needi
if (no such i exists) goto Step 4;
// Pi can be allocated
3. Work = Work + Allocationi // add to Work resources that Pi already has
Finish[i] = true;
goto Step 2
4. if (Finish[i] == false, for some i)
1. then the system is in deadlock state.
2. Moreover, if Finish[i]==false, then Pi is deadlocked

Algorithm requires an order of O(m x n2) operations to detect whether the system is in
deadlocked state

7.44
Example of Detection Algorithm
Five processes P0 through P4; three resource types
A (7 instances), B (2 instances), and C (6 instances)

Snapshot at time T0:


Allocation Request Available
ABC ABC ABC
P0 010 000 000
P1 200 202
P2 303 000
P3 211 100
P4 002 002

Sequence <P0, P2, P3, P1, P4> will result in Finish[i] = true for all i

7.45
Example (Cont.)

P2 requests an additional instance of type C


Request
ABC
P0 000
P1 202
P2 001
P3 100
P4 002

State of system?
Can reclaim resources held by process P0, but insufficient
resources to fulfill other processes; requests
Deadlock exists, consisting of processes P1, P2, P3, and P4

7.46
Detection-Algorithm Usage
When, and how often, to invoke depends on:
How often a deadlock is likely to occur?
How many processes will need to be rolled back?
one for each disjoint cycle

If detection algorithm is invoked arbitrarily, there may be many


cycles in the resource graph and so we would not be able to tell
which of the many deadlocked processes caused the deadlock.

7.47
Recovery from Deadlock: Process Termination

Abort all deadlocked processes


Cons: Very costly processes could have been running for long time.
They will need to be restarted.
Abort one process at a time until the deadlock cycle is eliminated
Cons: High overhead since the deadlock detection algorithm is called each
time one process is terminated

In which order should we choose to abort?


1. Priority of the process
2. How long process has computed, and how much longer to completion
3. Resources the process has used
4. Resources process needs to complete
5. How many processes will need to be terminated
6. Is process interactive or batch?

7.48
Recovery from Deadlock: Resource Preemption

Resource preemption is another method to recover from


deadlocks
Selecting a victim which process to choose to preempt its
resources?
Minimize cost.

Rollback return to some safe state, restart process for that


state.
Process cannot continue as is, since its resources are
preempted
The rollback state should be such that the deadlock breaks
Starvation same process may always be picked as victim
One solution: include number of rollback in cost factor

7.49
End of Chapter 7

Operating System Concepts 9th Edition Silberschatz, Galvin and Gagne 2013, modified by Dmitri V. Kalashnikov and Venkatasubramanian

You might also like