Deadlock
Deadlock
Process P1 is holding
◦ an instance of resource type R2 and is waiting for an
instance of resource type R1.
Process P2 is holding
◦ an instance of R1 and an instance of R2 and is waiting for an
instance of R3.
◦
Process P3 is holding an instance of R3.
Given the definition of a resource-allocation graph, it can be shown that, if the
graph contains no cycles, then no process in the system is deadlocked. If the
graph does contain a cycle, then a deadlock may exist.
If each resource type has exactly one instance, then a cycle implies that a
deadlock has occurred. If the cycle involves only a set of resource types, each of
which has only a single instance, then a deadlock has occurred. Each process
involved in the cycle is deadlocked. In this case, a cycle in the graph is both a
necessary and a sufficient condition for the existence of deadlock.
If each resource type has several instances, then a cycle does not necessarily
imply that a deadlock has occurred. In this case, a cycle in the graph is a
necessary but not a sufficient condition for the existence of deadlock.
To illustrate this concept, we return to the resource-allocation graph depicted in
Figure 7.1. Suppose that process P3 requests an instance of resource
P1 → R1 → P2 → R3 → P3
→ R2 → P1 P2 → R3 → P3
→ R2 → P2
7.4.3 No Preemption
The third necessary condition for deadlocks is that there be
no preemption of resources that have already been allocated.
To ensure that this condition does not hold, we can use the
following protocol. If a process is holding some resources and
requests another resource that cannot be immediately allocated
to it (that is, the process must wait), then all resources the
process is currently holding are preempted. In other words, these
resources are implicitly released. The preempted resources are
added to the list of resources for which the process is waiting.
The process will be restarted only when it can regain its old
resources, as well as the new ones that it is requesting.
Alternatively, if a process requests some resources, we first
check whether they are available. If they are, we allocate them.
If they are not, we check whether they are allocated to some
other process that is waiting for additional resources. If so, we
preempt the desired resources from the waiting process and
allocate them to the requesting process. If the resources are
neither available nor held by a waiting process, the requesting
process must wait. While it is waiting, some of its resources
may be preempted, but only if another process requests them. A
process can be restarted only when it is allocated the new
resources it is requesting and recovers any resources that were
preempted while it was waiting.