|CS 321 Spring 2013 > Lecture Notes for Wednesday, April 3, 2013|
Deadlock is tricky to deal with, particularly since it is often caused by a race condition. Deadlock is generally prevented either through careful debugging, or by avoiding concurrent programming entirely.
There are a number of more mechanical ways to deal with deadlock; we will discuss some of these. However, none of these methods is widely applicable, and therefore none is entirely satisfactory. In particular, we will look at the following.
Everything we do in software development has a cost. This includes dealing with deadlock. If the cost of the fix is worse than the problem it fixes, then it is better not to fix the problem. So maybe we can simply ignore the deadlock (but not, of course, if we wish to write correct, working code).
Given that the first three conditions hold, we can detect resource deadlock by checking for cycles in the resource graph.
One way to recover from deadlock by establishing checkpoints: places at which the state is saved so that we can back up to the checkpoint and do something different.
Note that, strictly speaking, the checkpoint idea is extrememly common. Deadling with deadlock by killing a program and restarting it, is essentially the same as establishing a checkpoint at the start of the program.
The Banker’s Algorithm can give us a way to navigate through times when resource allocation is tricky.
The idea is to consider the store of available resources as a bank. Allowing a process to acquire a resource means granting that resource a line of credit. We wish to avoid breaking the bank. A situation is safe if there is a way to bring all processes to completion that involves granting each in turn all the resources it will ever request. Here is the procedure.
By the definition of “safe”, all processes will eventually execute. However, some may wait a long time.
Another downside of the Banker’s Algorithms is that it must know in advance the maximum amount of resources each process will ever request.
We can prevent deadlock if we can change the structure of our software so that one of the four conditions will never happen. There are various ways to do this, none of which is useful in many situations.
One example: To negate the circular-wait condition, number the processes, and require that no process may request a resource that is currently held by a process with a lower number.