1505905018deadlock Avoidance Os18 Etextq1

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 9

e-PG Pathshala

Subject: Computer Science


Paper: Operating Systems
Module 18: Deadlocks – Avoidance
Module No: CS/OS/18
Quadrant 1 — e-text
18.1 Introduction

In a multiprogramming environment, many processes compete for a finite number of


resources. If the resources requested by a process are not available, the process waits. If the
resources requested by this process are held by other waiting processes, the situation may lead to
a deadlock. The different ways to handle deadlocks are deadlock prevention, deadlock
avoidance, deadlock detection and recovery. In the previous module, we learnt different ways to
prevent deadlocks. In this module, we shall see how deadlocks are avoided.

In the previous module, we learnt that a system with resources can be depicted using a
resource-allocation graph. In a resource-allocation graph, processes are denoted using circles and
resource types are denoted using rectangles. The different instances of each resource type are
shown as dots within the rectangles. Processes and resource types are the nodes of the
resource-allocation graph. The edges show the dependency between the processes and the
resources. If there is an edge from a process to a resource, it means that the process is requesting
for an instance of the resource (request edge). If there is an edge from a resource to a process, it
means that an instance of the resource is assigned to the process (assignment edge).

18.2. Resource-Allocation Graph Algorithm for Deadlock Avoidance

Fig. 18.1 Resource-Allocation Graph for Deadlock Avoidance (Source: [1])

A variant of the resource-allocation graph is used to avoid deadlocks when the


system has only one instance of a resource type. In this graph, a new type of edge is added called
the claim edge. A claim edge is represented by a dashed line as shown in Figure 18.1. A claim
edge Pi  Rj indicates that process Pj will request resource Rj. All claim edges must appear in
the graph, initially. Resources must be claimed a priori in the system. That is, at the beginning,
the system should know the future requests of all the processes. These requests that would be
made in future are depicted using claim edges.

A claim edge Pi  Rj is converted to a request edge when process Pi actually requests for
resource Rj. When resource Rj is released by process Pi, the assignment edge Ri  Pi reconverts
to a claim edge Pi  Rj.

We will now learn how deadlocks can be avoided using this type of resource-allocation
graphs. Suppose Pi requests Rj. The resource-allocation graph would have had a claim edge
from Pi to Rj. The claim edge is now converted to a request edge Pi  Rj. The request edge Pi
 Rj is converted to an assignment edge Rj
 Pi. The resource-allocation graph now depicts how the state of the system would have been
after the resource Rj is allocated to Pi. The resource-allocation graph is now checked for cycles
using the cycle-detection algorithm. If there is no cycle, the system is in a safe state and the
resource can be allocated to Pi. If there is a cycle, process Pi has to wait. Pi is not allocated the
resource Rj immediately.

Thus, the resource-allocation graph alone is modified and the system is checked for safe
state. The actual allocation of resource is not done immediately. Only if the allocation would
result in a safe state, the actual allocation of resources is done.

Fig. 18.2 Unsafe State In Resource-Allocation Graph (Source: [1])

Consider the resource-allocation graph in Figure 18.2. P2 requests for resource R2 as


shown using the claim edge from P2 to R2 in Figure 18.1. This is converted to an assignment
edge in the resource-allocation graph as shown in Figure 18.2. The graph is now checked for
cycles. Since there is a cycle, the system understands that allocating
R2 to P2 will lead to a deadlock. The only instance of R1 is assigned to P1 and the only instance of
R2 is assigned to P2. P2 has requested for R1. It is known from the claim edge that process P1
may request for R2. If P1 requests for R2 (before releasing R1, then both the processes P1 and P2
will wait for a resource held by the other process. The system will go to a deadlocked state.
Therefore, R2 is not allocated to P2. Thus, deadlocks are avoided.

This method can be used to avoid deadlocks only if there is a single instance of each
resource type. If there are more instances of each resource type, Banker’s algorithm is used for
deadlock avoidance.

Banker’s Algorithm
In the Banker’s algorithm, each process must a priori declare its maximum use. This
should be done for any deadlock avoidance algorithm. The maximum resource need of each
process must not exceed the total number of resources in the system. When a user requests for
resources, the system checks whether the allocation of the request will result in a safe state. If,
after the allocation, the system will be in a safe state, resources are allocated. Else, the process
waits. When a process gets all its resources it must return them in a finite amount of time.

Data Structures for the Banker’s Algorithm

Let n denote the number of processes and m denote the number of resource types.

• Available: Vector of length m. If Available[j] = k, there are k instances of resource


type Rj available.

ABC
332
In the example shown above, there are three resource types A, B and C. The number of
available instances of resource types A, B and C are 3, 3 and 2 respectively.

• Max: n x m matrix. The n rows correspond to n processes and the m columns


correspond to the m resource types. If Max[i, j] = k, then process Pi may request at most
k instances of resource type Rj

ABC
P0 753
P1 322
P2 902
P3 222

In the example shown above, there are three resource types A, B and C and four
processes P0, P1, P2 and P3. The maximum need of process P0 can be 7 instances of
resource type A, 5 instances of resource type B and 3 instances of
resource type C. Similarly, the maximum need of the other processes P1, P2 and
P3 are also shown.

• Allocation: n x m matrix. The n rows correspond to n processes and the m columns


correspond to the m resource types. If Allocation[i,j] = k then process Pi is currently
allocated k instances of Rj.

ABC
P0 010
P1 200
P2 302
P3 211
In the example shown above, there are three resource types A, B and C and four
processes P0, P1, P2 and P3. The number of instances of resource type currently allocated
to each process is shown. Process P0 is currently allocated 0 instances of resource type A,
1 instance of resource type B and 0 instances of resource type C. Similarly, the current
allocation of the other processes P1, P2 and P3 are also shown.

• Need: n x m matrix. The n rows correspond to n processes and the m columns


correspond to the m resource types. This matrix shows the future need of each process. If
Need[i, j] = k, then Pi may need k more instances of Rj to complete its task.
Need [i, j] = Max[i, j] – Allocation [i, j]
That is, future need is a process’s maximum need minus the resources currently allocated.

Notations Used:

If X and Y are vectors of length n


 X ≤ Y iff X[i] ≤ Y[i] for all i = 1,2,…,n
That is, the ith element of vector X is less than or equal to the ith element of vector
Y, for all i.
Consider the following vectors X and Y
 If X = (1,7,3,2), Y = (0,3,2,1)

In the above Y ≤ X, because each element of vector Y is less than or equal to the
corresponding element of vector X. That is, the first element of Y is less than the first element of
X and so on.

Y < X, if Y ≤ X and Y≠ X

Each row in the matrices Allocation and Need is treated as a vector. For example, the ith row
of matrix Allocation and Need are referred to as Allocationi and Needi respectively.
The Banker’s algorithm comprises a safety algorithm and a resource-allocation algorithm.
For a given state of the system, the safety algorithm checks if the system is in a safe state. The
safety algorithm is given below:

Safety Algorithm

1. Let Work and Finish be vectors of length m and n respectively. Initialize:


Work = Available
Finish [i] = false for i = 1,2, …, n
2. Find an i such that both:
(a) Finish [i] = false
(b) Needi  Work
If no such i exists, go to step 4.

3. Work = Work + Allocationi


Finish[i] = true
go to step 2.

4. If Finish [i] == true for all i, then the system is in a safe state.

Whenever a request for resources comes from a process, the system runs the resource-
request algorithm and modifies the state of the system in the simulation as if the resource is
allocated. The actual state of the system is not modified; the data structures in the algorithm
alone are modified. The safety algorithm is run to check if the system still remains in a safe state.
The resource-request algorithm for process Pi is given below:

Resource-Request Algorithm for Process Pi

Requesti = request vector for process Pi. If Requesti [j] = k then process Pi wants k
instances of resource type Rj.

1. If Requesti  Needi go to step 2. Otherwise, raise error condition, since process has
exceeded its maximum claim.
2. If Requesti  Available, go to step 3. Otherwise Pi must wait, since resources are not
available.
3. Pretend to allocate requested resources to Pi by modifying the state as follows:
Available = Requesti;
Allocationi = Allocationi + Requesti;
Needi = Needi – Requesti;;

The safety algorithm is now run to check if the system is in a safe state with this
modified state.

If safe  the resources are allocated to Pi.


If unsafe  Pi must wait, and the old resource-allocation state is restored
We will understand how the algorithm works by an example as given below.

Example of Banker’s Algorithm


Consider 5 processes P0 through P4; 3 resource types A, B and C. There are 10 instances
of A, 5 instances of B and 7 instances of C.

The snapshot at time T0 is given below:

Allocation Max Available


ABC ABC ABC
P0 010 753 332
P1 200 322
P2 302 902
P3 211 222
P4 002 433

The content of the matrix Need is defined to be Max – Allocation. Matrix Need is given
below:

Need
ABC
P0 743
P1 122
P2 600
P3 011
P4 431

We will first check if the system is in a safe state in the current situation. For this, the
safety algorithm is run.

Allocation Need Available

ABC ABC ABC


P0 010 743 332
P1 200 122
P2 302 600
P3 211 011
P4 002 431

Vector Work is initialized to Available

Therefore, Work = Available = (3,3,2)


Finish[i] = false for i = 0,1,2,3,4
Let i = 0
Is Need0 ≤ Work? No, (7,4,3) is not less than or equal to (3,3,2)

Let i = 1
Is Need1 ≤ Work? Yes, (1,2,2) is less than or equal to (3,3,2) Therefore,
set Finish[1] = true. P1 added to the safe sequence < P1>

Work = Work + Allocation1 = (3,3,2) + (2,0,0) = (5,3,2) Let i

=2
Is Need2 ≤ Work? No, (6,0,0) is not less than or equal to (5,3,2)

Let i = 3
Is Need3 ≤ Work? Yes, (0,1,1) is less than or equal to (5,3,2) Therefore,
set Finish[3] = true , P3 added to safe sequence < P1, P3> Work = Work +
Allocation3 =(5,3,2) + (2,1,1) = (7,4,3)

Work = (7,4,4)
Let i = 4
Is Need4 ≤ Work? Yes, (4,3,1) is less than or equal to (7,4,3)

Set Finish[4] = true , P4 is added to safe sequence < P1 ,P3, P4 > Work
= Work + Allocation4 = (7,4,3) + (0,0,2) = (7,4,5)

Work = (7,4,5)
Now, check again the processes that were not added to the safe sequence. P0
and P2 are remaining.

So, let i = 0
Is Need0 ≤ Work? Yes
Set Finish[0] = true, P0 is added to safe sequence < P1 ,P3, P4 , P0> Work
= Work + Allocation0 =(7,4,5) + (0,1, 0) = (7,5,5)

Work = (7,5,5)
Let i = 2
Is Need2 ≤ Work? Yes
Finish[0] = true , P2 is added to safe sequence <P1 ,P3, P4 , P0 , P2 >
Work = Work + Allocation2 =(7,5,5) + (3,0,2) = (10,5,7)

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

Now, let P1 Request (1,0,2)


First, check if Request1  Available (that is, (1,0,2)  (3,3,2))  true.
Also, check if Request1  Need1 (that is (1,0,2)  (1,2,2))  true.

Now, the data structures are changed as if the request of P1 is granted. The future Need of P1 is
changed from (1,2,2) to (0,2,0). The Allocation of P1 is changed from (2,0,0) to (3,0,2) and the
resources available are changed to (2,3,0)

Allocation Need Available


ABC ABC ABC
P0 010 743 230
P1 302 020
P2 301 600
P3 211 011
P4 002 431

The system is now checked for a safety sequence. Executing safety algorithm shows that the
sequence <P1, P3, P4, P0, P2> satisfies the safety requirement. Therefore, the request of P1 can
be granted.

After P1’s request is granted, can request for (3,3,0) by P4 be granted?


No, resources are not available. Only (2,3,0) is available. P4 needs 3 instances of A, but only
2 instances of A are available.

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


P0 Request (0,2,0)

Check if Request0  Available


(0,2,0)  (2,3,0)  true.
Also, check if Request0  Need0 (that is (0,2,0)  (7,4,3))  true.
Now, change the data structures as if the request is granted and run the safety algorithm to check
for a safe sequence. The future Need of P0 is changed from (7,4,3) to (7,2,3). The Allocation of
P1 is changed from (0,1,0) to (0,3,0) and the resources available are changed from (2,3,0) to
(2,1,0).

Allocation Need Available


ABC ABC ABC
P0 030 723 210
P1 302 020
P2 301 600
P3 211 011
P4 002 431

The future need of any of the processes cannot be satisfied with the resources available.
Therefore, there is no safe sequence. Therefore, it is understood that the request of P0 should not
be granted.
18.5 Summary
This module discussed what is meant by a safe sequence. We learnt how deadlocks can be
avoided when there is a single instance for all resource types. We also learnt how deadlocks
can be avoided when there are multiple instances of resources using the Banker’s algorithm.

References
1. Abraham Silberschatz, Peter B. Galvin, Greg Gagne, “Operating System Concepts”,
Ninth Edition, John Wiley & Sons Inc., 2012.

You might also like