Transcript Document

Deadlock and Starvation
• Deadlock: A set of Processes holding resources and blocked
waiting for others held by a processes in the same wait set.
• Starvation: Resource is always granted to other waiting processes
• Example: 2 tape drives, P1 and P2 each hold one and need both
• Example: P0: wait(A); wait(B);
P1: wait(B); wait(A);
• Resource: The narrow bridge
• Deadlock Resolution: Cars back up (preemption and rollback)
• Starvation is possible.
Conditions Necessary for Deadlock
• Hold and wait: Processes partially allocate resources
• Limited Resources: There is a limited number of
resources of a particular type. Processes will block if
requesting a limited that is unavailable.
• No preemption: A resource can be released only
voluntarily by the process holding it.
• Circular wait: there exists a process set {P0, P1, …, P0}
where P0 is waiting for a resource that is held by P1, P1 is
waiting for a resource that is held by P2, …, Pn–1 is
waiting for a resource that is held by P0.
P0
wait (A);
wait (B);
P1
wait(B)
wait(A)
Exercise
Refer to the above figure
1. How are all four conditions present?
2. How can deadlock be prevented, avoided, and
detected?
Directed Resource Allocation Graph
• Process
Graph: A set of vertices & edges.
Two vertex categories:
1. Circles: represent Processes
{P1, P2, …, Pn}
2. Rectangles: represent Resource
types {R1,R2,…,Rm}
Two edge categories
1. Pi requests resource type
Rj: PiRj
2. Resource Rj instance assigned to
Pi: RjPi
Resource categories: CPU
cycles, memory files, I/O devices
Access: request, utilize, then
release
• Resource Type with 4
instances
• Pi requests Rj instance Pi
• Pi holding Rj instance Pi
Graph Cycles
• No cycles  no
deadlock.
• cycles 
– Deadlock if there is
only one instance per
resource type
– Deadlock possibility
several instances per
resource type and all
processes are waiting
for a resource
No Deadlock
Deadlock
Possible Deadlock
class B implements Runnable; class A implements Runnable;
{ private Lock one, two;
{ private Lock one, two;
public(Lock one,Lock two)
public(Lock one,Lock two)
{ this.one = one;
{ this.one = one;
this.two = two;
this.two = two;
}
}
public void run()
public void run()
{
try
{
try
{ two.lock();
{ one.lock();
doSomething();
doSomething();
one.lock();
two.lock();
doSomethingElse();
doSomethingElse();
}
}
finally
finally
{ two.unlock();
{ two.unlock();
one.unlock();
one.unlock();
} }
}
} }
}
Deadlock possible depending on timing, but sometimes will not occur
Handling Deadlocks
• Prevention: Eliminate one of the four necessary
conditions
• Avoidance: Ensure that the system will never enter a
deadlock state.
• Recovery: Allow the system to enter a deadlock state
and then recover.
• Ignore: Most operating systems, including UNIX and
WINDOWS, pretend that deadlocks never occur. It is up
to application programs to handle.
Deadlock Prevention
Eliminate one of the necessary conditions
• Hold and Wait
– sharable resources like read-only files are deadlock free
• Limited Resources
– Resources with unlimited instances are deadlock free.
• No Preemption
– Release all resources instead of blocking on a resource request.
The preempted resources are added to the resource wait list.
– Restart when all requested resources are available.
• Circular Wait (Disadvantage: Low resource utilization)
1. Impose a total ordering of resource types. Processes must
request resources in an increasing order of enumeration.
2. Processes cannot request resources when already holding
others.
Deadlock Avoidance
• The system must have advance knowledge of total needed resources
• Processes will not hold a resource forever
Safe state: A sequence of requests exist
that can be satisfied without deadlock
Safe state  no deadlocks
Unsafe state  possibility of deadlock
Avoidance disallows all unsafe states
Algorithm Pseudo code
System is initially safe
At each request for a resource
IF allocation causes an unsafe state
THEN block the process
ELSE grant the allocation
At each resource release
WHILE a blocked request can be granted safely
Grant the allocation; unblock the process
Resource Allocation Graph for
Deadlock Avoidance
• Dashed line: Pi to Rj
Pi may request Rj
• Solid line: Pi to Rj
Pi has requested Rj.
• Solid line: Rj to Pi:
Rj is assigned to Pi.
If resources with a single instance, implement a cycle detection algorithm
(Recall Union Find algorithm from Data Structures)
Dijkstra Banker’s Algorithm
Original algorithm’s purpose: Prevent runs on a bank
Notation
request[p, r] = k means process p wants k instances of resource type r
available[r] = k means there are k resources of type r available
need[p,r] = k means process p potentially needs k resources of type r
allocated[p,r] = k means process p owns k resources of type r
Pseudo code upon processor p request for resource r
1.
Throw Exception IF request[p,r[ > need[p,r]
2.
3.
IF request[p,r] > available[r], block process p
Tentatively allocate requested resources to process p:
available[r] -= request[p,r];
allocated[p,r] += request[p,r];
need[p] -= request[p,r]
4.
IF system state is safe THEN allocation is okay
ELSE restore original state and block process p
Safe State Algorithm
Safety Algorithm
1. Let work and finish be arrays of length R and P, respectively.
2. Copy available to work
FOR p = 1 to P, finish [p] = false
3. WHILE a p exists such that
for all r, finish [p]=false AND need[p, r]  work[r]
THEN for all r, work[r] += allocated[p, r]
finish[i]=true
4. IF finish[p]==true for all p, then safe system state (allocate resources)
ELSE block process
Data structures for this algorithm: P processes, R resources
Available:
available[r]=k k instances of resource r are available
Max: max[p, r]=k
Process p may request up to k of resource r
Allocated:
allocated[p, r]=k
Process p owns k instances of
resource r
Need: need[p, r] = k Process p may need k more of resource r
Note: need [p,r] = max[p, r] – allocation [p,r]
Deadlock Avoidance Example
5 processes P0 through P4 and 3 resources (A,B,C)
Resource A has 10 instances
Resource B has 5 instances
• The system state: Safe
Resource C has 7 instances.
– < P1, P3, P4, P2, P0> satisfies
the safety criteria.
Need = Max – Allocated
ABC ABC
ABC
• P1 now requests (1,0,2).
P0 7 4 3 = 7 5 3 – 0 1 0
– Request  Need
P1 1 2 2 = 3 2 2 – 2 0 0
– Request  Available
P2 6 0 0 = 9 0 2 – 3 0 2
– Execute safety algorithm:
P3 0 1 1 = 2 2 2 – 2 1 1
– <P1, P3, P4, P0, P2> satisfies
the safety criteria
P4 4 3 1 = 4 3 3 – 0 0 2
Available = 3 3 2
• Questions:
– Is P4 request for (3,3,0) safe?
– Is P2 request for (0,2,0) safe?
Deadlock Detection
Allow Deadlock, detect its occurrence, recover
Design Issues
•
•
•
•
•
When, and how often, to invoke the detection algorithm?
Is it possible to detect the cause?
How often is a deadlock is likely to occur?
How many processes are part of the deadlock?
Which group of processes should we abort?
– All involved in the deadlock?
– One at a time till the deadlock cycle is eliminated?
• Can we roll back to a safe state and try again?
– What is the same process is always the victim
– How many rollbacks should we allow?
• How to determine the cost of recovery?
– Process priority and type (interactive or batch)
– Process run time, and the estimated time to completion.
– Resources the process has used and those still needed
Deadlock Detection
Single resource instances
Single Instance
• Maintain wait graph
– Nodes are processes.
– Pi  Pj if Pi is waiting for Pj
• Periodically invoke an
algorithm to detect a
cycle in the graph
• The text claims cycle
detection requires
O(|V|2). Is that true?
Resource allocation
graph
wait-for
graph
Deadlock Detection
Multiple Resource Instance Algorithm
Data structures for this algorithm: P processes, R resources
Available:
Allocated:
Request:
available[r]=k k instances of resource r are available
allocated[p, r]=k Process p owns k instances of resource r
request[p, r] = k Process p requests k instances of resource r
Let work and finish be arrays of length R and P, respectively
Copy available to work
FOR all p and r // no circular wait if process doesn’t hold any resources
IF allocated[p,r]  0, then finish[p] = false ELSE finish[p] = true
// No circular wait for a process that can be fully satisfied
WHILE p exists where for all r, finish[p] == false and request[p,r]  work[r]
SET work[p] += allocated[p,r] AND finish[p] = true
IF finish[p] == false, for some p, 1  p  P
THEN the system and process p is in deadlocked
Deadlock Detection Example
Description of the system state
Five processes: P0 through P4
Three resource types
A has 7 instances
B has 2 instances
C has 6 instances
Allocated Request Available
ABC
ABC
ABC
P0 0 1 0
000
000
P1 2 0 0
202
P2 3 0 3
000
P3 2 1 1
100
P4 0 0 2
002
• Sequence <P0, P2, P3, P1, P4> causes
finish[p] = true for all p
• If P2 requests a type C resource, the
request array becomes:
P0
P1
P2
P3
P4
ABC
000
201
001
100
002
• We can reclaim P0 resources, but
there are not sufficient resources to
fulfill the other requests
• Deadlock involves P1, P2, P3, and P4
Conclusion
• Most current operating systems ignore
deadlocks. It is left to the application developer
to handle
• There is not one approach that is sufficient
• The eventual solution is to combine the three
basic approaches of prevention, avoidance, and
detection
• Different resource classes would employ a
selected solution