Many thanks to Filipe Fortes and Adam Ruprecht for their contributions to today's notes. -GMK
Reading:
Chapter 8
A Quick Review
A resource is an abstraction for any reason to wait. For our purposes,
resoures are non-sharable and serially reusable. That means that only
one process (or thread) can use a resource at the same time. The resource
becomes available for use only after the first user has released it.
Def'n: Deadlock - The condition that arises when there is a set of processes (or threads) such that each process (or thread) holds a resource that another process in the set is waiting to acquire. This situation forces all processes (or threads) in the set to wait forever.
Conditions Necessary For Deadlock:
All of these conditions are necessary for deadlock to occur. If any condition
is not satisified, the system is not in a deadlocked state. If it is
impossible to satisfy all four conditions concurrently, deadlock is impossible.
Resource Allocation Graphs
Resource allocation graphs can be used describe a system's use of
resources and demonstrate the existance of deadlocks.
Consider a resource allocation graph, G, a set of tuples, {V, E}, where V is a vertex and E is an edge.
There are two types of verticies:
There are two types of edges:
Deadlock Detection
Single Instance of Each Resource Type
Given a resource allocation graph, we can perform deadlock detection, perhaps as part of the idle process. This works nicely, because if a deadlock exists, the deadlocked processes will be blocked, not running, so idle will have the opportunity to run.If only a single instance of each resource type exists, then the system is deadlocked, if and only if there is a cycle in the graph. The most common solution is to kill -9 the processes in the set
Multiple Instances of Each Resource Type
If multiple instances of a single resource type exist, we must reduce the graph before checking for cycles. Unless we reduce the graph, a cycle does not indicate deadlock.Reducing the graph involves asking the question, "What happens when this runnable process finishes?" Basically, we assume that any process that isn't waiting for a resource completes and releases the resources that it is hold. This in turn makes those resources available to other processes. The process of finding runnable processes and removing them from the graph is repearted, until there are no more runnable processes.
The system is in a deadlocked state, if and only if the graph is not reducible. That is to say that the graph shows the system to be deadlocked if and only if all runnable processes have been reduced (this implies a cycle).
Deadlock Prevention
The goal of deadlock prevention is to prevent the necessary conditions from being satisified:
- Mutual Exclusion - make resources sharable - example: read-only files
- Hold-and-wait - if requested resource is unavailable, release all currently allocated resources before waiting. But this allows livelock. Another approach is to request all resources at once in a single request. If processes request resources only once and are granted the requested resources at once, hold-and-wait is not satisfied and livelock is not possible.
- No preemption - make resources preemptable
- Circular wait - allow processes to wait for resources, but ensure that the waiting can't be circular. One approach might be to assign a precedence to each resource and force processes to allocated resources in order of increasing precedence. That is to say that if the highest precedence resource a process currently holds is X, the process cannot request any resource with precedence <= X. This forces resource allocation to follow a particular and non-circular ordering, so circular wait cannot occur. waiting can happen, but can't be circular - how do it? - allow holding only one; if request another resource, must free one holding (also hold-and-wait - as are all solutions of this type to this problem) - OR assign numerical value (precedence) to each type of resource, if max currently held precedence is X, then may only request (or grant) resources with precedence greater than X
Deadlock Avoidance
Deadlock prevention disallows many different ways of using resources, because they could potentially lead to deadlock. But if the resources suffer reasonable low contention, deadlock could be unlikely. The result is that resources are left idle to prevent the infrequent or unlikely occurance of deadlock. This leads to low resource utilization. Deadlock avoidance is an alternative to deadlock prevention that can yield higher resource utilization. But nothing comes for free. The cost of deadlock avoidance is that we must know much more about how the various processes will request the resources.The goal of deadlock avoidance is to ensure that the system is always in a safe state. When in a safe state, deadlock is not possible. But if we are in an unsafe state, deadlock could occur. The behavior of the collection of processes determines if deadlock results in an unsafe state, whereas no action of a process can lead to deadlock if the system is in a safe state.
To ensure that the system remains in a safe state, we must know the following for each process:
- The number of each type resource that it currently holds
- The maximum number of each type of resource that it might need
- The number of each type of resource that exist in system
Example:
System:
2 processes
1 type of resource
5 instance of that resource
Maximum needs:
P1: 4 instances
P2: 4 instances
Initial state:
P1 - 0 allocated
P2 - 0 allocated
Later (safe):
P1 - 1 allocated
P2 - 2 allocated
Later (unsafe):
P1 - 2 allocated
P2 - 2 allocated