Professional Documents
Culture Documents
Deadlock:
Deadlock is a common problem in multi-programming where several
processes share a specific type of mutually exclusive resource.
A Deadlock is a situation where each of the computer process waits for a
resource which is being assigned to another process. In this situation,
none of the processes gets executed since the resource one needs, is held
by some other process which is also waiting for some other resource to be
released.
Deadlock is a situation where a set of processes are blocked because each
process is holding a resource and waiting for another resource acquired
by some other process.
Example of Deadlock:
Let us assume that there are two processes (P1 and P2) and two different
resources (R1 and R2). R1 is assigned to P1 and R2 is assigned to P2.
After some time, P1 demands for R2 which is being used by P2. P1 halts
its execution since it can't complete without R2. P2 also demands for R1
which is being used by P1, therefore P2 also stops its execution.
In this scenario, a cycle is being formed among the two processes. None
of the process can progress and they are all waiting. The computer
becomes unresponsive since all the processes got blocked.
Starvation:
Starvation is a phenomenon associated with the priority scheduling
algorithms, in which a process ready to run can wait indefinitely because
of low priority. In heavily loaded computer system, a steady stream of
higher-priority processes can prevent a low priority process from ever
getting the CPU.
Starvation is a resource management problem where a process does not
get the resources it needs for a long time because the resources are being
used by other higher priority processes.
Livelock:
There is a variant of deadlock called livelock. This is a situation in which
two or more processes continuously change their state in response to
changes in the other process (es) without doing any useful work. This is
similar to deadlock in that no progress is made but differs in that neither
process is blocked or waiting for anything.
A human example of livelock would be two people who meet face-to-
face in a corridor and each moves aside to let the other pass, but they end
up swaying from side to side without making any progress because they
always move the same way at the same time.
become stuck waiting for resources currently held by the deadlock and by
other waiting processes. Unfortunately, this slowdown can be
indistinguishable from a general system slowdown when a real-time
process has heavy computing needs.
1) Deadlock Ignorance:
If deadlocks only occur once in a year or so, it may be better to simply let
them happen and reboot as necessary than to incur the constant overhead
and system performance penalties associated with deadlock prevention or
detection. This is the approach that both Windows and UNIX take.
2) Deadlock Prevention:
Deadlocks can be prevented by preventing at least one of the four
required conditions: mutual exclusion, hold and wait, no pre-emption, and
circular wait.
Mutual exclusion:
Shared resources such as read-only files do not lead to deadlocks.
Unfortunately, some resources such as printers and tape drives,
require exclusive access by a single process.
So, we should not avoid the mutual exclusion.
Hold and wait: To prevent this condition processes must be prevented
from holding one or more resources while simultaneously waiting for one
or more others. There are several possibilities for this.
Require that all processes request all resources at one time. This
can be wasteful of system resources if a process needs one resource
early in its execution and doesn't need some other resource until
much later.
Require that processes holding resources must release them before
requesting new resources, and then re-acquire the released
resources along with the new ones in a single new request. This can
be a problem if a process has partially completed an operation
using a resource and then fails to get it re-allocated after releasing
it.
Either of the methods described above can lead to starvation if a
process requires one or more popular resources.
No pre-emption: Pre-emption of process resource allocations can prevent
this condition of deadlocks, when it is possible.
One approach is that if a process is forced to wait when requesting
a new resource, then all other resources previously held by this
3) Deadlock Avoidance:
It requires that the system has some additional a priori information
available.
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, i.e. to ensure safe state.
A resource allocation state is defined by the number of available
and allocated resources, and the maximum requirements of all
processes in the system.
4) Deadlock Detection and Recovery:
Allow system to enter deadlock state.
Use detection algorithm to detect the deadlock and provide recovery
scheme.
Edges in RAG:
Assign Edge: If a resource is already assigned to a process then it is
called assign edge.
Request Edge: In future if a process wants some resource to complete the
execution the it is called request edge.
Examples of RAG:
If there is a cycle in the RAG and each resource in the cycle provides
only one instance, then the processes will be in deadlock.
So cycle in single-instance resource type is the sufficient condition for
deadlock.
But in multi-instance resource type, cycle is not the sufficient condition
for deadlock.
Wait-for Graph:
Wait-for graph is a variation of RAG.
A wait-for graph can be constructed from a resource allocation graph by
eliminating the resources and collapsing the associated edges.
An arc from Pi to Pj in a wait-for graph indicates that process Pi is waiting
for a resource that process Pj is currently holding.
Cycles in the wait-for graph indicate deadlocks.
Wait-for-graph is one of the methods for detecting the deadlock situation.
This method is suitable for smaller database. In this method a graph is
drawn based on the transaction and their lock on the resource.
Example:
Banker’s Algorithm:
The banker’s algorithm is a resource allocation and deadlock avoidance
algorithm that tests for safety by simulating the allocation for
predetermined maximum possible amounts of all resources, then makes a
“safe state” check to test for possible activities, before deciding whether
the allocation should be allowed to continue or not.
Banker’s algorithm is named so because it is used in banking system to
check whether a loan can be sanctioned to a person or not. Suppose there
are n number of account holders in a bank and the total sum of their
money is S. If a person applies for a loan, then the bank first subtracts the
loan amount from the total money that the bank has and if it is greater
than S then only the loan is sanctioned. This is maintained to satisfy all
the account holders who come to withdraw their money at a time.
In other words, the bank would never allocate its money in such a way
that it can no longer satisfy the needs of all its customers. The bank
would try to be in safe state always.
Characteristics:
If a process demands the resources, then it has to wait.
It should know the maximum resource required of all the processes in
advance.
Resources are maintained that fulfill the needs of at least one process.
There are limited resources in the system.
If a process gets all the needed resources, then it must return the resources
within a restricted period.
Disadvantages:
During processing, it does not permit a process to change its
maximum need.
All the processes should know in advance about their maximum
required resources.
It permits the requests to be provided in constrained time.
Data Structures:
Available: It is an array of length m. It represents the number of
available resources of each type. If Available[j] = k, then there
are k instances available, of resource type R(j).
Max: It is an n x m matrix which represents the maximum number of
instances of each resource that a process can request. If Max[i][j] = k,
then the process P(i) can request at most k instances of resource
type R(j).
Allocation: It is an n x m matrix which represents the number of
resources of each type currently allocated to each process.
If Allocation[i][j] = k, then process P(i) is currently allocated k instances
of resource type R(j).
Need: It is an n x m matrix which indicates the remaining resource
needs of each process. If Need[i][j] = k, then process P(i) may
need k more instances of resource type R(j) to complete its task.
Need[i][j] = Max[i][j] – Allocation [i][j].
This step is done because the system needs to assume that resources
have been allocated to the process Pi. So there will be less resources
available after allocation. The number of allocated instances will
increase for Pi. The need of the resources of Pi will reduce. That's what
is represented by the above three operations.
After completing the above three steps, check if the system is in safe
state by applying the safety algorithm. If it is in safe state, proceed to
allocate the requested resources. Else, the process has to wait longer
without getting the requested resources.
Safety Algorithm:
This algorithm describes whether the need of all the processes can
be fulfilled or not by the system.
Step 1: Let Work and Finish be two vectors of length m (number
of resource types) and n (number of processes), respectively.
Initially, Work[j] = Available[j] and
Finish[i] = false for i = 0, 1, ..., n – 1.
This means, initially no process has finished and the number of
available resources is represented by the Available array.
Step 2: Find an index i (Process Pi) such that
Finish[i] == false and Need[i][j] <= Work[j]
If no such i present, then proceed to step 4.
This means, we need to find an unfinished process whose need can
be satisfied by the available resources.
Step 3: Perform and go to step 2.
Work[j] = Work[j] + Allocation[i][j]
Finish[i] = true
This means, the resources are allocated to Pi so that Pi can
complete its task. After completing its task Pi releases all its
previously allocated resources which are then added to the
currently available resources and Pi is marked as finished. Then
the loop is repeated to check the same for all other processes.
Step 4: If Finish[i] == true for all i, then the system is in a safe
state which indicates that all the processes are finished.
Numerical Example:
Consider the following system that contains five processes P0, P1, P2,
P3, P4 and three resource types A, B and C. The allocation, max and
available matrices are given below. Here, A has 10, B has 5 and C has 7
instances.
Answer of Q1:
Process Need
A B C
P0 7 4 3
P1 1 2 2
P2 6 0 0
P3 0 1 1
P4 4 3 1
Available resources of type A, B and C are 3, 3 and 2 respectively.
Here, j denotes the number of resource types and i denotes the number
of processes. In this problem, j = 3 and i = 5.
Work[j] = Available[j] = [3, 3, 2] for j = 0, 1, 2
Finish[i] = 0 for i = 0, 1, …, 4
For P0: Need[0][j] <= Work[j] i.e. [7, 4, 3] <= [3, 3, 2] is false.
For P1: Need[1][j] <= Work[j] i.e. [1, 2, 2] <= [3, 3, 2] is true.
Work[j] = Work[j] + Allocation[1][j]
i.e. Work[j] = [3, 3, 2] + [2, 0, 0] = [5, 3, 2]
Finish[1] = true
For P2: Need[2][j] <= Work[j] i.e. [6, 0, 0] <= [5, 3, 2] is false.
For P3: Need[3][j] <= Work[j] i.e. [0, 1, 1] <= [5, 3, 2] is true.
Work[j] = Work[j] + Allocation[3][j]
i.e. Work[j] = [5, 3, 2] + [2, 1, 1] = [7, 4, 3]
Finish[3] = true
For P4: Need[4][j] <= Work[j] i.e. [4, 3, 1] <= [7, 4, 3] is true.
Work[j] = Work[j] + Allocation[4][j]
i.e. Work[j] = [7, 4, 3] + [0, 0, 2] = [7, 4, 5]
Finish[4] = true
For P0: Need[0][j] <= Work[j] i.e. [7, 4, 3] <= [7, 4, 5] is true.
Work[j] = Work[j] + Allocation[0][j]
i.e. Work[j] = [7, 4, 5] + [0, 1, 0] = [7, 5, 5]
Finish[0] = true
For P2: Need[2][j] <= Work[j] i.e. [6, 0, 0] <= [7, 5, 5] is true.
Work[j] = Work[j] + Allocation[2][j]
i.e. Work[j] = [7, 5, 5] + [3, 0, 2] = [10, 5, 7]
Finish[2] = true
All the processes are completed. So the system is in safe state and the
safe sequence is <P1, P3, P4, P0, P2>.
Answer of Q2:
Process Need
A B C
P0 7 4 3
P1 1 2 2
P2 6 0 0
P3 0 1 1
P4 4 3 1
For P0: Request[0][j] <= Need[0][j] i.e. [1, 3, 0] <= [7, 4, 3] is true.
Request[0][j] <= Available[j] i.e. [1, 3, 0] <= [3, 3, 2] is true.
Available[j] = Available[j] – Request[0][j]
i.e. Available[j] = [3, 3, 2] – [1, 3, 0] = [2, 0, 2]
Allocation[0][j] = Allocation[0][j] + Request[0][j]
i.e. Allocation[0][j] = [0, 1, 0] + [1, 3, 0] = [1, 4, 0]
Need[0][j] = Need[0][j] – Request[0][j]
i.e. Need[0][j] = [7, 4, 3] – [1, 3, 0] = [6, 1, 3]
Now, apply safety algorithm.
Exercise:
Consider the following system that contains five processes P0, P1, P2,
P3, P4 and four resource types A, B, C and D. At T0 the system has the
following state.