Operating Systems Lecture 12: Deadlocks and Prevention - Prof. Mark Corner, Study notes of Operating Systems

A transcript from a university lecture on operating systems, specifically focusing on the topic of deadlocks. The lecture covers examples of deadlock situations, necessary conditions for deadlocks, methods for deadlock detection and prevention, and the challenges of recovering from deadlocks.

Typology: Study notes

Pre 2010

Uploaded on 08/19/2009

koofers-user-f76-1
koofers-user-f76-1 🇺🇸

10 documents

1 / 2

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CMPSCI 377 Operating Systems Spring 2009
Lecture 12: March 10
Lecturer: Mark Corner Scribes: Bruno Silva,Jim Partan
12.1 Deadlocks
We introduced deadlocks in the last lecture. Here is another example of a program which can deadlock:
Thread A
lock(L1);
lock(L2);
Thread B
lock(L2);
lock(L1);
If Thread A acquires lock L1, and then the scheduler switches to Thread B, which acquires lock L2, then
this program will deadlock. Neither thread releases the lock it holds, and each is trying to acquire the lock
which the other holds. In fact, without recursive locks, this simple example will also deadlock:
Thread A
lock(L);
lock(L);
12.1.1 Necessary Conditions for Deadlock
Here are the conditions necessary for a deadlock to occur; note that all of them are necessary, and none is
sufficient:
1. finite resources: the resources are held in a mutually-exclusive way, and they can be exhausted, causing
waiting.
2. hold-and-wait: each thread holds one resource while waiting for another.
3. no preemption: threads only release resources voluntarily. No other thread (or the OS) can force the
thread to release its resources.
4. circular wait: we have a circular chain of waiting threads.
12.1.2 Deadlock Detection
Deadlocks can be detected while the program is running, by running cycle detection algorithms on the graph
that defines the current use of resources.
12-1
pf2

Partial preview of the text

Download Operating Systems Lecture 12: Deadlocks and Prevention - Prof. Mark Corner and more Study notes Operating Systems in PDF only on Docsity!

CMPSCI 377 Operating Systems Spring 2009

Lecture 12: March 10

Lecturer: Mark Corner Scribes: Bruno Silva,Jim Partan

12.1 Deadlocks

We introduced deadlocks in the last lecture. Here is another example of a program which can deadlock:

Thread A lock(L1); lock(L2);

Thread B lock(L2); lock(L1);

If Thread A acquires lock L1, and then the scheduler switches to Thread B, which acquires lock L2, then this program will deadlock. Neither thread releases the lock it holds, and each is trying to acquire the lock which the other holds. In fact, without recursive locks, this simple example will also deadlock:

Thread A lock(L); lock(L);

12.1.1 Necessary Conditions for Deadlock

Here are the conditions necessary for a deadlock to occur; note that all of them are necessary, and none is sufficient:

  1. finite resources: the resources are held in a mutually-exclusive way, and they can be exhausted, causing waiting.
  2. hold-and-wait: each thread holds one resource while waiting for another.
  3. no preemption: threads only release resources voluntarily. No other thread (or the OS) can force the thread to release its resources.
  4. circular wait: we have a circular chain of waiting threads.

12.1.2 Deadlock Detection

Deadlocks can be detected while the program is running, by running cycle detection algorithms on the graph that defines the current use of resources.

12-2 Lecture 12: March 10

Define this graph as follows: it has one vertex for each resource (r 1 ,... , rm) and one vertex for each thread (t 1 ,... , tn). If a resource ri is held by thread tj , then we add an edge from vertex ri to vertex tj. If a thread tk is trying to acquire resource r, then we add an edge from vertex tk to vertex r.

Given this graph, we can run a cycle detection algorithm. If a cycle is found, there is a deadlock.

Detecting a deadlock is much easier than recovering from a deadlock. Several possible approaches might be to kill all of the threads in the cycle, or kill the threads one at a time, forcing them to release resources, and hope that this will break the deadlock.

While this may sound easy, it is not. Killing threads generally doesn’t release their resources cleanly (locks, memory, files, etc). This is essentially the rollback problem, to back out all the actions of a thread. Databases usually include rollback mechanisms, which can be quite complicated, and it is not always possible to roll back all the actions of a thread (consider a thread which outputs hard-copy printed pages).

As a general guideline, do not use functions like pthread cancel(), which kills a thread, unless you really know what you are doing.

12.1.3 Deadlock Prevention

While it is hard to resolve a deadlock which has been detected, fortunately it is fairly easy to prevent deadlocks from ever happening.

The key is that the conditions above for deadlock are all necessary. We just have to ensure that at least one condition cannot be true. We definitely cannot get rid of the problem of finite resources; that is something we have to live with. And in many cases it can be difficult to get rid of the conditions of hold-and-wait and lack of preemption.

But we can eliminate circular waiting. One standard way of doing this is to have a so-called canonical ordering of the locks. This means that the programmer must always acquire the locks in a specified order, such as first lock1, then lock2, then lock3, etc. By doing so, we will ensure a system whose thread/resource graph is cycle-free, and therefore the system will be deadlock-free.