(Latest Revision:
Oct 30, 2008
)
Chapter Seven -- Deadlocks -- Lecture Notes
- 7.0 Objectives
- Description of Deadlock
- Present Methods for Preventing or Avoiding Deadlock
- Present Methods for Detecting and Recovering from Deadlock
- 7.1 System Model
- Our model system contains processes and resources.
- The set of all resources is partitioned into equivalence classes
called resource types.
- Examples of resources: CPU cycles, printers, drives, memory, files,
semaphores.
- A running process may request resources at any time.
- A process uses resources according to this pattern:
request-use-release.
- A process may request multiple resources at the same time. However
the request may not exceed the number existing in the system. For
example if there are two tape drives and four DVD's in the system,
the process may request up to (but no more than) two tape drives and
four DVD's with one request.
- A process must wait until everything it has requested can be granted
- all at once. (Why is this
necesary?)
- The request and release operations may be implemented as system
calls or through the use of synchronizations tools such as
semaphores.
- Deadlock occurs in a group of processes when each
process is waiting for a resource that can only be acquired when one
of the other processes in the group releases it.
- A deadlock is stable. None of the processes involved can acquire
all the resources for which it is waiting.
- 7.2 Deadlock Characterization
- Section 7.2.1 -- Necessary Conditions
- Mutual Exclusion -- If multiple processes are
permitted to access all resources concurrently then deadlock
can't happen.
- Hold and Wait -- If processes never hold a resource
while waiting for a resource then deadlock can't happen.
- No preemption -- If "enough" preemption of resources
occurs, then deadlock can't happen. (In the extreme,
suppose that whenever a process waits for a resource the
system takes away all the resources it currently holds.
Deadlock would be impossible. )
- Circular Wait -- If cycles in the resource
allocation graph cannot occur then there cannot be any
deadlock.
- Section 7.2.2 -- Resource-Allocation Graph (RAG)
- Processes are Nodes -- Circles
- Resource Types are Nodes -- Squares
- Each instance of the resource type is represented by a
dot in the square
- A solid request-edge points from a process to a resource
type
- When a request is granted the request edge is instantaneously
transformed into an assignment edge extending from one of the
instances inside the resource to the process.
- If there are no cycles in the RAG then there is no
deadlock in the system.
- If there is only one instance of every resource type, and if
there is a cycle in the RAG then the processes on the cycle are
deadlocked.
- If some of the resource types have more than one instance
then it is possible for a cycle to exist in the RAG when
there is no deadlock.
- 7.3 Methods for Handling Deadlock
- Deadlock Prevention: Make rules about how requests and
assignments are done so that one or more of the necessary conditions
for deadlock are missing.
- Deadlock Avoidance: Place restrictions on assignments only
when the system is about to enter an "unsafe state" - from which it
could immediately "go out of control" and become deadlocked. (The
avoidance algorithms we study require extra, advance information
concerning the types and numbers of resources each process could
request during its lifetime.)
- Deadlock Detection and Correction: Place no restrictions on
the system but notice when deadlock has occurred and recover.
- Ignore the problem: Maybe deadlocks are rare and we can deal
with the problem just by rebooting when we notice that some
processes appear "frozen." This will not always be adequate -
imagine that the computer is flying a plane.
- 7.4 Deadlock Prevention (ways of preventing cycles from forming)
- Mutual Exclusion: If X is a resource and the OS immediately
grants every request for access to X, then X can never be part of a
circular wait - it can never be 'involved' in a deadlock. For
example, it is OK for any number of processes to share a read-only
file. Obviously sometimes exclusive access to resources is required.
So we can't prevent deadlock simply by deciding to make all
resources sharable all the time.
- Hold and Wait:
- Method: Require each process to request and be allocated all its
resources before it begins execution, or
- Method: allow a process to request resources only when it has
none.
- Disadvantage of these methods: resources may be allocated
but unused for long periods of time.
- Disadvantage of these methods: If a process waits for more than
one resource, there is no guarantee they will all become
available at the same time.
- No Preemption:
- Method: If a process P requests a resource that is not
immediately available, P immediately loses all resources it
holds and is required to wait for the new resource, plus all
its 'old' resources.
- Method: Suppose a process P requests some resources that are
held by a process Q. If Q is waiting for a resource
then P takes what it wants from Q and this is added to the
request for which Q is waiting. (If no process waits on a
waiting process then there are no cycles.) If Q is not
waiting then P waits. (The OS can preempt stateless things like
registers and memory without harming Q. However if it takes
away something like a printer, it may as well terminate Q.)
- Disadvantage of these methods: More time lost waiting for
resources, including the possibility of indefinite postponement
when waiting for multiple resources.
- Circular Wait:
- Method: Impose a total ordering on resource types and forbid
requests that go against the order. (Also a process may not
make consecutive requests for instances of the same resource
type.) These rules assure that, in chains of waiting
processes, the resource numbers are strictly increasing, and so
there cannot be any cycles.
- Disadvantage of this method: It may lead to longer periods of
holding some resources, and thus to decreased availability of
resources.
- 7.5 Deadlock Avoidance
- The idea of deadlock avoidance is for the OS to recognize unsafe
states - states from which the system could slip, out of
control, into deadlock. To recognize unsafe states, the OS needs to
have information about the possible resource needs of each
process.
- Section 7.5.1 -- Safe State
- Basically an unsafe state is one which will turn in to a
deadlock if all processes immediately request their remaining
possible needs.
- The state is safe if it is not unsafe. If the system state is
safe then even if all processes max out their requests, they
are able to finish executing in some order P0,
P1, P2, ... , Pn. When each
process exits, it gives up its resources. Freed resources
become available to the next process in the sequence.
- When a system practices deadlock avoidance it uses the
following criteria to decide whether to grant resources to a
requesting process P. The request is granted if:
- P is not asking to exceed its declared maximum possible
needs,
- the resources are currently available (free), and
- granting the request will leave the system in a safe
state.
Typically if P tries to exceed its max, the OS will terminate
P. If condition #1 is true but #2 or #3 fails, the system
makes P wait for the resources. (They will be granted later -
when available and 'safe.')
- PROBLEMS WITH THAT: The system is burdened with doing a safety
check each time there is a resource request. Processes
sometimes have to wait for resources that are available.
Resource utilization and throughput can be reduced. There is
also the possibility of
starvation.
- Section 7.5.2 -- Resource-Allocation Graph
- We can create an augmented resource allocation graph (AUGRAG)
by adding (dotted) claim edges from processes to resources,
representing each request that each process might make.
- If there is just one instance of each resource type, then
"unsafe" is equivalent to "cycle in the AUGRAG." This is a
conceptually simple way to characterize safety. Cycle
detection algorithms typically require O(N2) work,
where N is the number of processes in the system. This method
does not work when there are multiple instances of some
resource types, because in that case there can be a cycle in
the AUGRAG of a safe system.
- Section 7.5.3 -- Banker's Algorithm
- The Banker's Algorithm is a deadlock avoidance scheme that
works when there are multiple instances of resource types. It
is generally less efficient than the cycle-detection scheme.
- Before it does anything else a new process must declare the
maximum number of instances of each resource type that it may
need.
- Various data structures are required. See the GLOSSARY
here.
- Section 7.5.3.1 -- Safety Algorithm
- Read the algorithm to check for safety
here.
- Section 7.5.3.2 -- Resource Request Algorithm
- Read the banker's resource-request algorithm
here.
- Section 7.5.3.3 -- An Illustrative Example
- 7.6 Deadlock Detection
- Another alternative: Have the system run a deadlock detection
algorithm and have the system run a recovery algorithm after it
detects a deadlock.
- Section 7.6.1 -- Single Instance of Each Resource Type
- In this case there is a deadlock if and only if there is a
cycle in the resource allocation graph. Therefore the OS can
detect deadlock by maintaining a RAG that represents the system
and doing cycle checks from time to time. There is a more
compact graphical representation called a wait-for graph
that can be used instead. The algorithm will tend to be more
efficient if run on this graph.
- Section 7.6.2 -- Several Instances of a Resource Type
- If there are multiple instances of some resource types then one
can detect deadlock with an algorithm similar to the safety
algorithm. (We can view the safety algorithm as checking to
see if there would be a deadlock if all the processes were to
max out their requests.)
- See
the deadlock detection algorithm.
- Section 7.6.3 -- Detection-Algorithm Usage
- In the system model we use, the addition of a request edge to a
RAG is always the last step in the creation of a deadlock. If
we check for deadlock every time a process blocks requesting a
resource, then we will detect each deadlock as soon as it
happens. Using our textbook's deadlock detection algorithm, this
would require a lot of processing - a lot of overhead.
- Since deadlocks are usually quite rare, it may suffice to check
for deadlock only about as often as deadlock occurs. We also
might make use of heuristics, such as low CPU utilization or the
presence of processes in the system that have been waiting for
resources for an unusually long time.
- 7.7 Recovery from Deadlock
- Section 7.7.1 -- Process Termination
- To break a deadlock we can just abort all the deadlocked
processes. However, much of their unfinished work will go to
waste.
- Instead we can select and abort victim processes one at
a time, stopping when the deadlock is broken. This brings up
the question of what criteria to use to select victims:
- Kill the lowest priority process?
- Kill the youngest process?
- Kill the process that has most "life" ahead of it?
- Kill the process with the fewest stateful resources?
- Kill the process that needs the most additional
resources?
- Kill the smallest possible number of processes?
Also, there is the problem of determining when the deadlock is
broken. Will it be necessary to run an expensive deadlock
detection algorithm after each process is aborted?
- When the OS aborts a process its data and/or allotted devices
may be left in an incorrect state. Consider a process that was
in the midst of printing a file or burning a CD.
- Section 7.7.2 -- Resource Preemption
- Instead of killing deadlocked processes we can take resources
from some and give them to others until the deadlock is broken.
- We have to consider here too the bases for victim selection.
- If we don't abort a victim process we will probably need to
roll it back and restart it at a point in its execution before
it acquired the resources that have been preempted. Problem:
How?
- Starvation is a possibility when we abort or rollback processes and
restart them. There is no guarantee that they will not become
deadlocked again, and be aborted or rolled back again. We may want
to build in a mechanism to "spare" former victims.