CS 453 Operating Systems Lecture 7: Deadlock PDF
Document Details
Uploaded by IntelligibleSapphire
Maharaja Sayajirao University of Baroda
Tags
Summary
This document provides a lecture on deadlocks in operating systems. It details what deadlocks are, using real-world examples such as traffic jams. It also covers how they occur, with a visual representation demonstrating the issue.
Full Transcript
CS 453 Operating Systems Lecture 7 : Deadlock 1 What is Deadlock? Every New Yorker knows what a gridlock alert is - it’s one of those days when there is so much traffic that nobody can move. Everything just sits there! The REAL reason...
CS 453 Operating Systems Lecture 7 : Deadlock 1 What is Deadlock? Every New Yorker knows what a gridlock alert is - it’s one of those days when there is so much traffic that nobody can move. Everything just sits there! The REAL reason for gridlock is that there are so many cars getting stuck in the intersection that traffic on the cross streets can’t get through. As a result, that street backs up as well, and after a while, if there are enough cars on the street, no one can move because all the intersections are blocked and one way or the other. Essentially, this is what deadlock is. Processes effectively block each other, because each process is standing in the way of another process trying to finish its jobs. Each process is holding something that the other process wants, and as a result, neither can move foreward. 2 Example of Deadlock Process A wants to copy a file from disk drive A to drive B. It’s holding drive A and waiting for drive B. Process B wants to copy a file from disk drive B to drive A. It’s holding drive B and waiting for drive A. Imagine two processes running on the same computer. Both are trying to copy files. One process is trying to copy from Drive A to Drive B. The other process is doing the reverse. And they both request (and get) the drive from which they are reading. The end result is that they are both waiting for the drive onto which they are going to write - which the other one is holding onto for dear life because they are going to read from it. Without some intervention, this standoff can continue forever - unless we unplug the computer first! 4 How Does Deadlock Occur? Resource 1 Process A Process B Process A has Process B has Resource 1 and Resource Resource 2 and seeks Resource 2 seeks Resource 1 2 This diagram illustrates the problem pretty well. The green circles represent the resources and the blue rectangles the processes. The green arrows show that Resource 1 belongs to Process A and that Resource 2 belongs to Process B. The blue arrows show that Process A is waiting for Resource 2 and that Process B is waiting for Resource 1. Unless they can share these resources, we have a 2-process deadlock. We’ll see quite soon that deadlocks do not necessarily involve two processes. This little standoff can involve a larger circle of processes, which actually makes it more dangerous. It isn’t a matter of starving one or two processes - it can actually involve a fairly large number directly or indirectly! 3 Processes and Resources A process using a resource goes through the following sequence of events: Request: The process asks the operating system for the resource. If it isn’t available immediately, it waits until it is available. Use: The process does whatever operations it needs to do using the resources that it requested. Release: The process surrenders the resource back to the operating system There are essentially 3 events that describe the role that a resource plays in the life of a process. The process must first request the use of the resource. Since it may very well not be available immediately, the process may have to wait. This is the stage where the process may be deadlocked. After securing the resource and whatever other resources it may need, the process uses the resource. After it’s finished with its need of the resource, it releases it and now it can be used by other processes. Release is also important, because if processes do not release their resources, other processes can’t use them. The Necessary Conditions For Deadlock A deadlock can only happen when these four conditions are met: – Mutual exclusion – At least one resources can be used by only one process at a time – Hold and wait – A process will hold a resource while waiting for another one. – No preemption – A resource cannot be taken away from a process that has not released it voluntarily. – Circular wait – E.g, P0 is waiting for a resource that P1 is holding, P1 is waiting for a resource that P2 is holding, and P2 is waiting for a resource that P0 is holding. There are four conditions that must be true for deadlock to occur. These are mutual exclusion, hold and wait, lack of pre-emption and circular wait. Mutual exclusion means that only one process can use a resource at a time. This is fairly common. Only one process can read from a keyboard at a time, for example. But even resources that can be shared may only allow x number of processes to use it at a time. The sign that barber shops used to have “8 chairs, no waiting” assumed that there would never be more than 8 customers in the shop at once to get their hair cut. If there were, then there would be some waiting. Hold and wait means that a process can hold onto a resource while it waits for another. The assumption is that it is using the two resources in conjunction, such as copying or printing a file. No pre-emption means that a process cannot be strip of a resource without surrendering it voluntarily. Pre-empting the resources of a process means that when it resumes, it must somehow replace the resource that it lost and find a reasonable place to resume execution. Circular waiting means that A is waiting for B which is waiting for C which is waiting for A. This, taken together with hold and wait, means that they are each holding something that the other one wants. Mutual exclusion means that the very fact that they are holding it prevents the other from having it. And no preemption means that neither will give it up. 5 Resource-Allocation Graph R1 R2 R3 P1 P2 P3 P4 R4 R5 R6 A resource-allocation graph is a directed graph that shows us each resource (along with each instance of it which can be reserved) with the processes that have requested them and are waiting for them, each process with the resources that are reserved them. An arrow pointing from resource to process means that the process is holding the resources. The arrow pointing from resource to process means that the process is waiting for the resource. If any of these arrow completed a cycle or circuit, then that would indicate circular wait. You don’t see any circuits here, so there is no circular wait, hence no deadlock. 6 Resource-Allocation Graph Showing Deadlock R1 R2 R3 P1 P2 P3 P4 R4 R5 R6 A circuit does not necessarily mean a deadlock, although it will indicate the possibility of one. Here you’ll notice that there is clearly a circuit from R5 to P2 to R2 to P3 back to R5. That means that there is circular wait. But since R5 has two instances, each of which can be reserved, we need that second circuit from R5 to P1 to R2 to P3 back to R5. Since this completes a circuit which includes the same resource (R2), we have a deadlock. 6 Resource-Allocation Graph Showing A Circuit But No Deadlock R1 R2 R3 P1 P2 P3 P4 R4 R5 R6 This diagram includes a circuit, but there is no deadlock. R5 has a second instances which was reserved by P1. Since P1 can complete its execution - it has all the resources it needs) - it will free R5 and then P3 can use R5 and complete its own execution. Lastly, P2 can finish. Since they all can finish, there is no deadlock. 6 How To Handle Deadlock We can prevent deadlock from ever happening. We can allow deadlock, detect it when it happens and recover from it. We can pretend that deadlock never happens. How do we handle deadlock? For all practical purposes, we can either prevent, detect it whenever it happens and then recover from it, or simply pretend that it never happens. Many operating systems take this last approach, which is not without problems. There is a story of one system that was shut down and they discovered on it a process that had been waiting for ten years. Ignoring deadlock can potentially lead to situations like this. 7 Deadlock Prevention Deadlock prevention means that we will eliminate one of the four necessary conditions for deadlock: We cannot eliminate mutual exclusion We can forbid processes to request resources while holding others before executing. (Eliminates hold and wait) We can require that a process denied a resource must give up the others. (Eliminates no pre- emption) We can require that resources be requested in a specific order. (Eliminates circular waiting) Preventing deadlock, in theory, is simple: prevent one of the four necessary conditions from becoming true. The most immediate problem is that you cannot prevent the first condition in most instances where you find it. The only way to eliminate mutual exclusion is a hardware solution: increase the number of devices. But even that will always eliminate mutual exclusion. Any possibility is to prevent processes from holding resources while they wait for other resources. This prevents the hold and wait condition. We can require that a process that was denied a resource give up the ones that it is holding. This adds the possibility of pre-emption, preventing deadlock. Lastly, we can require that resources be requested and allocated in a specific order. This eliminates the possibility of circular waiting. 8 Eliminating Hold and Wait There are two ways of eliminating hold and wait: – Processes must request all their resources before executing (resource requests must come before all system requests). – Processes cannot request resources before releasing others. There are two ways of eliminating hold and wait: The first possibility is that process request all the resources before starting. This eliminates the scenario of a process holding one resource while waiting for another. The other possibility is that process cannot request resources if it is holding any. This would require a process to surrender its resources before requesting any others. Pitfalls With Eliminating Hold and Wait Both methods will lead to low resource utilization because a resource will be held without being used for extended periods of times. This can lead to starvation because a process may wait indefinitely if one or more of the required resources is in heavy demand. Both methods will lead to low utilization because resources will sit idle but reserved for long periods of time. A process would request everything at the start but not use one or more of these resources for quite some time. Additionally, it opens up the possibility of starvation because a process may wait forever for the situation where all the resources it needs to all be available at the same time. Eliminating Lack of Pre-emption Process A is holding Resource 1 and requests Resource 2. Resource 2 is not available because Process B is holding it. We can require that Process A give up Resource 1 immediately or discover that Process B is waiting for Resource 1 and allow it to be re-allocated. We can also allow pre-emption to occur. This means that we can take a resource away from one process and give it to another that it waiting for it. Eliminating Circular Wait We can establish a precedence in which resources must be requested. If a requested resource is not available, we wait until it is before requesting any other resources. This precedence should follow the normal order of usage for these resources. Eliminating circular wait requires us to establish some kind of order to the manner in which processes request resources. If processes must always get Resource 1 before waiting for Resource 2, then circular wait is impossible and therefore there can never be a deadlock. Deadlock Avoidance Deadlock prevention algorithms reduce resource utilization and systems throughput. If the operating system knows in advance about a process’s resource requests, it can determine whether or not they can be fulfilled without a risk of deadlock. This strategy is called deadlock avoidance. The problem with preventing deadlock is that it also makes our use of the system resources much less efficient. Our utilization of resources will be diminished as will our systems throughput. Since we want to maximize throughput and resource utilization and not minimize them, deadlock prevention may not be worthwhile design goals. There is an alternative that may be more worthwhile. Let’s give the operating system prior notice of what resources a process may request. Now we can determine the likelihood of deadlock and avoid situations where we are more likely to encounter it. This is what we mean by deadlock avoidance. 9 What is a Safe State? Deadlock Unsafe Safe A state is safe if the system can allocate resources to the various processes in some particular order and avoid deadlock in doing so. An unsafe state is a state that may lead to deadlock. Not all unsafe states are actual deadlock. Our goal in avoiding deadlock is to avoid the unsafe states. Since safe states cannot lead to deadlock, we can avoid it without incurring as high a cost as we would in eliminating the necessary conditions for deadlock. 10 An Example of a Safe State Maximum Needs Current Needs Total available = 15 tape drives P0 10 5 P1 6 3 P2 6 2 P3 3 2 Imagine a situation where we have four processes that are looking to use some of a system’s 15 tape drives. They each have indicated what their maximum needs could be. Although they could request a total of 25 tape drives on a system that only has 15, currently they have only requested 12 tape drives. That leaves 3 tape drives available. With those three tape drives, P1, P2 or P3 could finish their work. As each finishes, the drives that they have reserved become available for the remaining processes. Then there will be the extra tape drives available that P2 needs and eventually even the 5 tape drives that P0 needs. Since all the processes can get the necessary resources and run through completion, this is a safe state. An Example of an Unsafe State Maximum Needs Current Needs Total available = 15 tape drives P0 10 7 P1 6 3 P2 6 2 P3 3 2 If any of these processes were to request another tape drive, the system would not be able to fulfill the request. This means that it is not a safe state Resource-Allocation Graph Showing a Safe State claim edge R1 P1 P1 R2 R3 P1 request edge assignment edge It is possible to use resource-allocation graphs to show whether a state is safe or unsafe if each resource has only one instance. In addition to the assignment edges and request edges that we discussed earlier, we add another type of edge: the claim edge. Processes must inform the operating system of the resources that they may request over their lifetime. These potential requests, or claims, are shown as claim edges. Claims are not requests, because the requests have not yet been made, but the process has the right to request them if necessary. We will now include them in our analysis. If we have a circuit, there is a possibility that there will be a circular wait. Since there is only one instance of each resource, there is mutual exclusion also, as well as hold and wait and no pre-emption. This could become a deadlock, although it may not. We will avoid these because without unsafe states, there is no deadlock. 11 Resource-Allocation Graph Showing an Unsafe State R1 P1 P1 R2 R3 P1 In this case, there is a circuit, so we are obviously in an unsafe state. 11 Resource-Allocation Graph Showing a Deadlock R1 P1 P1 R2 R3 P1 This graph shows a state in deadlock. Like the unsafe state, there is a circuit, but what makes this different is that the claim edge is replaced by a request edge. Now our circuit indicates that all the conditions are present to create a deadlock. 11 The Banker’s Safety Algorithm Let Work and Finish are vectors of length m and n respectively. Initialize Work := Available and Finish[I] for I := 1 to n Complete := False REPEAT Find I such that (Finish[I] = false) AND Need[I] Need THEN Error(Exceeded maximum claim) ELSE IF Requesti > Available THEN Wait(Resources are not available) Have the system pretend to allocate the requested resource. This means that for Pi: Available := Available - Requesti; Allocationi := Allocationi + Requesti; Needi := Needi + Requesti; IF the resulting state is safe THEN Complete transaction and allocate resources ELSE Pi waits for the resources and old allocation is restored. The last algorithm tells us if the system is safe. But will it be safe if we allocate a resource (or more than one resource) to a process? Let’s pretend to allocate the resource or resources and see if the system is in a safe state. If it is, we’ll do the allocation. If not, we won’t. 12 Banker’s Algorithm - An Example Alloc. Max. Need Avail. P1 0 4 4 P2 2 5 P3 4 8 Let’s look at a simple example. Imagine that there are three processes, which have been allocated our one resource as shown in the slide. They each have a maximum allowed allocation of as shown. Banker’s Algorithm Example – What Is the Need? safe Alloc Max. Need Avail P1 0 4 4 4 P2 2 5 3 P3 4 8 4 The first step is to calculate what they might need. For Process P1, it is 4 because a maximum of 4 minus an allocation of 0 yields 4. For process P2, it is 5 minus 2 yielding a need of 3. For process P3, it is 8 minus 4 yielding a need of 4. With the sequence , we have determined that the system is in a safe state. With 4 instances of the resource available, we could complete any of the three processes; let’s say that we complete P2 first.Now we can free the 2 that P2 is holding. With the 6 available, we can complete either P1 or P3; let’s compete P1 first. Since there is nothing to free we don’t change the amount available and we complete P3 Banker’s Algorithm Example – What If We Allocate A Few More? unsafe Alloc Max. Need Avail P1 2 4 2 1 P2 3 5 2 P3 4 8 4 Let’s allocate 2 instances of our resource to P1 and one more to P2. With only one instance of the resource left, there is no process whose potential need can be met. So we cannot be certain that any will run to completion. The system is in an unsafe state and the allocation was not a prudent move. Banker’s Algorithm Example – 3 Types of Resources Alloc Max Need Avail A B C A B C A B C A B C P0 0 1 0 7 5 3 3 3 2 P1 2 0 0 3 2 2 P2 3 0 2 9 0 2 P3 2 1 1 2 2 2 P4 0 0 2 4 3 3 Let’s take a look at a more typical situation. There are three different types of resources, A, B and C. Shown here is their current allocations, the maximum allocations that they may request and what remains available. Our first step is to calculate the needs. Banker’s Algorithm Example – Calculating the Needs Alloc Max Need Work A B C A B C A B C A B C P0 0 1 0 7 5 3 7 4 3 3 3 2 P1 can P1 2 0 0 3 2 2 1 2 2 get its need and finish P2 3 0 2 9 0 2 6 0 0 P3 2 1 1 2 2 2 0 1 1 P4 0 0 2 4 3 3 4 3 1 P0 has 0 instances of A, 1 instance of B and 0 instances of C. It has the right to 7 instances of A, 4 instances of B and 3 instances of C. 7 instances of A minus 0 allocated instances of A equals a need of 7 instances of A. 5 instances of B minus 1 allocated instance of B equals a need of 4 instances of B. 3 instances of C minus 0 allocated instances of C equals a need of 3 instances of C. We now do the same for processes P1, P2, P3, and P4. When we finish, we see that P1 can get everything that it may need, so it will run through completion. Banker’s Algorithm Example – After Finishing Process P1 Alloc Max Need Work A B C A B C A B C A B C P0 0 1 0 7 5 3 7 4 3 5 3 2 P1 0 0 0 0 0 0 0 0 0 P2 3 0 2 9 0 2 6 0 0 P3 can P3 2 1 1 2 2 2 0 1 1 get its need P4 0 0 2 4 3 3 and finish 4 3 1 After we re-allocate the 2 instances of A that P1 actually is holding, we have 5 A’s, 3 B’s and 2 C’s. With this, we can satisfy P3 and it can run through completion. Banker’s Algorithm Example – After Finishing Process P3 Alloc Max Need Work A B C A B C A B C A B C P0 0 1 0 7 5 3 7 4 3 7 4 3 P1 0 0 0 0 0 0 0 0 0 P2 3 0 2 9 0 2 6 0 0 P3 0 0 0 0 0 0 0 0 0 P4 can get its need P4 0 0 2 4 3 3 4 3 1 and finish Once P3 finishes, we re-allocate its 2 A’s, 1 B and 1 C, making 7A’s, 4 B’s and 3 C’s available for re-allocation. Now we can finish P4. Banker’s Algorithm Example – After Finishing Process P4 Alloc Max Need Work A B C A B C A B C A B C P0 0 1 0 7 5 3 7 4 3 7 4 5 P1 0 0 0 0 0 0 0 0 0 P2 can P2 3 0 2 9 0 2 6 0 0 get its need and finish P3 0 0 0 0 0 0 0 0 0 P4 0 0 0 0 0 0 0 0 0 We can now free up the 2 C’s that belong to P4 and and now we have 7 A’s, 4 B’s and 5 C’s. This is enough to allow us to complete P2. Banker’s Algorithm Example – After Finishing Process P2 Alloc Max Need Work A B C A B C A B C A B C P0 0 1 0 7 5 3 7 4 3 10 4 7 P1 0 0 0 0 0 0 0 0 0 P0 can P2 0 0 0 0 0 0 0 0 0 get its need and finish; P3 0 0 0 0 0 0 0 0 0 P4 0 0 0 0 0 0 0 0 0 Lastly, we free up the 3A’s and 2 C’s that P2 has. This leaves us with enough to complete P0. Banker’s Algorithm Example – After Finishing Process P0 Alloc Max Need Work A B C A B C A B C A B C P0 0 0 0 0 0 0 0 0 0 10 5 7 P1 0 0 0 0 0 0 0 0 0 The system P2 0 0 0 0 0 0 0 0 0 is safe P3 0 0 0 0 0 0 0 0 0 P4 0 0 0 0 0 0 0 0 0 There is a sequence in which we can complete all the processes if they do need their maximum allocation. The system is safe. Banker’s Algorithm Example – Can We Grant P1’s Request? P1 requests Alloc Max Need Avail (1, 0, 2) It is less A B C A B C A B C A B C than the P0 0 1 0 7 5 3 7 4 3 3 3 2 available resources P1 2 0 0 3 2 2 1 2 2 P2 3 0 2 9 0 2 6 0 0 P3 2 1 1 2 2 2 0 1 1 P4 0 0 2 4 3 3 4 3 1 Let’s examine a request of process P1 for 1 A, 0 B’s and 2 C’s. Since this is less than what is available, we have the resources available for the request, but will it leave us in a safe state? Banker’s Algorithm Example – After We Grant P1’s Request A similar Alloc Max Need Avail execution of our A B C A B C A B C A B C algorithm P0 0 1 0 7 5 3 7 4 3 will find the 2 3 0 sequence P1 3 0 2 3 2 2 0 2 0 P2 3 0 2 9 0 2 6 0 0 P3 2 1 1 2 2 2 0 1 1 P4 0 0 2 4 3 3 4 3 1 Let’s pretend to allocate it. This leave us with 2 A’s, 3 B’s and 0 C’s available. We have enough for P1 to run to completion, even if it needed its maximum allocation. After de-allocating its 3 A’s and 2 C’s, we would have 5 A’s, 3 B’s and 2 C’s available. With this, we could run P3 through completion. Then we could free its resources, which would give us 7 A’s, 4B’s and 3 C’s. With this we could easily complete P4, P0 and P2. Thus, this request can be made without placing the system in an unsafe state. Banker’s Algorithm Example – Can We Grant P4’s Request? P4 requests Alloc Max Need Avail (3, 3, 0) It is more A B C A B C A B C A B C than the P0 0 1 0 7 5 3 7 4 3 available 2 3 0 resources P1 3 0 2 3 2 2 0 2 0 P2 3 0 2 9 0 2 6 0 0 P3 2 1 1 2 2 2 0 1 1 P4 0 0 2 4 3 3 4 3 1 If P4 were to request 3 A’s and 3 B’s, we would be unable to fulfill the request because we do not have the resources available - we are short 1 A. Banker’s Algorithm Example – Can We Grant P0’s Request? P0 requests Alloc Max Need Avail (0, 2, 0) It is less A B C A B C A B C A B C than the P0 0 1 0 7 5 3 7 4 3 available 2 3 0 resources P1 3 0 2 3 2 2 0 2 0 P2 3 0 2 9 0 2 6 0 0 P3 2 1 1 2 2 2 0 1 1 P4 0 0 2 4 3 3 4 3 1 Let’s see what happens if P0 requests 2 B’s. It’s less than the available resources, But does it place us in an unsafe state? Banker’s Algorithm Example – Recalculating P0’s Allocation Alloc Max Need Work A B C A B C A B C A B C Adding to P0 0 3 0 7 5 3 7 1 3 P0’s 2 0 0 allocation P1 3 0 2 3 2 2 0 2 0 P2 3 0 2 9 0 2 6 0 0 P3 2 1 1 2 2 2 0 1 1 P4 0 0 2 4 3 3 4 3 1 Let’s add the 2 B’s to P0’s allocation and recalculate its need and what would be available. Banker’s Algorithm Example – Recalculating P0’s Allocation Alloc Max Need Avail A B C A B C A B C A B C There is P0 0 3 0 7 5 3 7 1 3 not enough 2 0 0 left for P1 3 0 2 3 2 2 0 2 0 anyone’s need; P2 3 0 2 9 0 2 6 0 0 it is not safe P3 2 1 1 2 2 2 0 1 1 P4 0 0 2 4 3 3 4 3 1 The problem is that 2 A’s and 0 B’s or C’s leave us unable to meet any possible requests by other processes. This request won’t be granted because it places us in an unsafe state. Deadlock Detection If a system does not provide for deadlock avoidance or prevention, then it must provide: – an algorithm for deadlock detection – an algorithm for deadlock recovery Some systems don’t avoid or prevent deadlock. What they do is detect it and recover from it. That means that such systems need an algorithm for each of these two tasks. 13 Detecting Deadlock With Single-Instances of Each Resource P5 R1 R3 R4 P1 P2 P3 R2 P4 R5 In the case of single-instance resource, we can use a graphical approach. Let’s take another look at our resource allocation graph. What we will do is simplify this by redrawing the request edges that currently run from process to resource. Instead, let’s have them point directly to the process holding the requested resource. Detecting Deadlock Corresponding Wait-For Graph P5 P1 P2 P3 P4 This is what the graph looks like after the redrawing the request edges. Now we know at a single glance that P4 is waiting for a resource that P1 is holding; which resource is not important. Similarly P1 is waiting for a resource that P2 is holding and P2 is waiting for a resource that P4 is holding. It is fairly straightforward to write a program that can detect whether there is a circuit like this in such a graph. Detecting Deadlock With Multiple-Instances of Each Resource Let Work and Finish be vector of length m and n respectively. Initialize Work := Available FOR I := 1 To n IF Allocation 0 THEN Finish[i] := False; ELSE Finish[i] := True; WHILE there exists an I such that (Finish[i] = False) AND (Requesti