Deadlockwith powerpoint notes
Because deadlock is a difficult concept that often looks easy. I have provided yet MORE notes on deadlock extracted from previous
notes of Dr. Baker and myself. They are provided as a good reivew to assure you
understand deadlock.
Deadlock Topics
• Definition: Deadlock • Necessary conditions for deadlock • Strategies for dealing with deadlock • Strategies for detecting deadlock • Deadlock in different models of resource
allocation
Types of Resources
• Reusable • Consumable
Reusable Resources• Fixed number of units • Neither created nor destroyed • Used by one process at a time and not depleted by that
use • Processes obtain resources that they later release for
reuse by other processes • several different possible modes of access:
– exclusive – read/write (can be modeled by multi-unit) – shared (not treated by text)
• operations: request, grant/acquire, release • Deadlock occurs if each process holds one resource and
requests the other
Consumable Resources• Created (produced) by a process • Destroyed (consumed) by a process • Operations: request/receive (implies
consume), produce/send • Deadlock may occur if the receive
operation can block • Potential deadlock situations are more
difficult to detect, and reproduce, by testing
Deadlock Example with Reusable Resources
Process P1:
request(R1);
... request(R2); ... release(R2
); ... release(R1);
R1 critical section
R2 critical section
Process P2:
request(R2);
... request(R1); ... release(R1
); ... release(R2);
R1 critical section
R2 critical section
Resource Allocation Graph of a Deadlocked System
Deadlock Trajectory Diagram
Example of Deadlock with Consumable Resources
P1 P2
….. …..
receivefrom(P2, &M2); receivefrom(P1, &M1);
…… …..
sendto(P2, M1); sendto(P1, M2);
Deadlock occurs if the receive from operation is blocking.
Natural Questions about Deadlock
• What are the fundamental causes of deadlock?
• How can we deal with deadlock?
Now that we have looked at examples of some specific cases of deadlock, it is time to look at deadlock from a general point of view.
The 4 Necessary Conditions for Deadlock
• Exclusive access (mutual exclusion) – only one process may use a resource at a
time• Wait while holding (hold-and-wait)
– A process can continue to hold a resource while requesting another
• No preemption – A process cannot be forced to give up
resources before it chooses to give them up
• Circular wait – There is a cycle of hold-and-wait
relationships
The 3 Approches/Strategies for Dealing with Deadlock
• Prevention - apply design rules to insure it can never occur
• Avoidance - dynamically steer around deadlocks
• Detection - hope deadlocks will not occur, but recover when one does
Deadlock Prevention Approaches
• All of the four conditions are necessary for deadlock to occur.Hence, by preventing any one of them we prevent deadlock.
• Exclusive access (mutual exclusion) – redesign to eliminate the need for mutual exclusion
(Can you think of an example?) • Wait while holding (hold-and-wait)
– If a process holding resources is denied a further request, the process must release all its resources and rerequest them
– Require that a process request all of its required resources at one time• No preemption
– If a process requests a resource that is currently held by another process, the OS preempts the second process and requires it to release its resources
• Circular wait • Define a linear ordering of resources and require allocations be
requested only in this order
Cycle Implies Different Allocation Orders
Ordered Allocation
Process P1:
request(R1);
..
. request(R2);
..
. release(R2);
..
. release(R1);
R1 critical section R2 critical
section
Process P2:
request(R1);
..
. request(R2);
..
. release(R2);
..
. release(R1);
R1 critical section R2 critical
section
Trajectory Diagram for Ordered Allocation
Release Before Request
Process P1:request(R1); ... release (R1); request(R2); ... release(R2); R1 critical section R2 critical sectionProcess P2:request(R2); ... release (R2); request(R1); ... release(R1); R2 critical section R1 critical section
Request All at Once
Process P1:request(R1, R2); ... release(R1, R2);
R1 critical section
R2 critical sectionProcess P2:
request(R1, R2); ... release(R1, R2);
R1 critical section
R2 critical section
Deadlock Avoidance• A decision is made dynamically whether the
current resource allocation request will, if granted, potentially lead to a deadlock
• Requires knowledge of worst-case future process requests
• Approaches: – Postpone starting a process if its demands might lead
to deadlock,i.e. while resources it may need are held by others
– Postpone granting an incremental resource request to a process if granting the allocation might lead to deadlock
Requirements for Deadlock Avoidance
• Maximum resource requirement must be stated in advance
• Processes under consideration must be independent; no synchronization requirements
• There must be a fixed number of resources to allocate
• No process may exit while holding resources
System with Potential for Deadlock
Process P1:
request(R1); ... request(R2); ... release(R2); ... release(R1);
R1 critical section
R2 critical section
Process P2:
request(R2); ... request(R1); ... release(R1); ... release(R2);
R1 critical section
R2 critical section
Trajectory to Unsafe State
Resource Allocation State Transition Diagram
How Deadlock Is Avoided
How do we know a state is safe?
• Start in the given state • Simulate running each process to
completion,by allocating its maximum resource requirements,and then releasing all resources
• If all processes can complete, the state is safe
Representing State as Set of Tables
• Claim matrix [Process][Resource]: Integermaximum requirement of each resource type for each process
• Allocation matrix [Process][Resource]: Integercurrent allocation of each resource type for each process
• Resource vector [Resource]: Integertotal number in system of each resource type
• Allocation vector [Resource]: Integernumber currently available of each resource type
Determination of a Safe State: initial state
Determination of a Safe State: P2 runs to completion
Determination of a Safe State: P1 runs to completion
Determination of a Safe State: P3 runs to completion
An Unsafe State: initial state
An Unsafe State: P1 requests one unit each of R1 and R3
How to Detect Deadlock?
• Similar to detecting an unsafe state
• Simulate execution of unblocked processes, assuming they will complete and release all resources
Deadlock Detection with Tables
R1 R2 R3 R4 R5 P1 0 1 0 0 1 P2 0 0 1 0 1 P3 0 0 0 0 1 P4 1 0 1 0 1
Request Matrix Q
R1 R2 R3 R4 R5 P1 1 0 1 1 0 P2 1 1 0 0 0 P3 0 0 0 1 0 P4 0 0 0 0 0
Allocation Matrix A
R1 R2 R3 R4 R5 2 1 1 2 1
Resource Vector R1 R2 R3 R4 R5 0 0 0 0 1
Available Vector
Deadlock Detection with Tables (Step 2)
R1 R2 R3 R4 R5 P1 0 1 0 0 1 P2 0 0 1 0 1 P3 0 0 0 0 1 P4 1 0 1 0 1
Request Matrix Q
R1 R2 R3 R4 R5 P1 1 0 1 1 0 P2 1 1 0 0 0 P3 0 0 0 0 0 P4 0 0 0 0 0
Allocation Matrix A
R1 R2 R3 R4 R5 2 1 1 2 1
Resource Vector R1 R2 R3 R4 R5 0 0 0 1 1
Available Vector
When Deadlock is Detected• Abort all deadlocked processes • Back up each deadlocked process to
some previously defined checkpoint, and restart it from the checkpoint – original deadlock may reoccur
• Kill deadlocked processes until deadlock no longer exists
• Preempt resources until deadlock no longer exists
Choose which Process to Abort
• Least amount of processor time consumed so far • Least number of lines of output produced so far • Most estimated time remaining • Least total resources allocated so far • Lowest priority
Graph Models of System Resource Allocation States
• Wait-for graphs (WFG) • Single-unit resource allocation graphs • Multi-unit resource allocation graphs • General resource allocation graphs (GRG)
Wait-For Graphs (WFG)• Nodes correspond to processes (only).
Single-Unit Resource Allocation Graphs
Multiunit Resource Allocation Graphs
Dining Philosophers
Example
Dining Philosophers Problem
What is the Dining Philosophers Problem?
Significance of this Problemo Potential for deadlock and starvation
o Academic benchmark for evaluation and comparison of synchronization and mutual exclusion mechanisms
o An example for demonstrating various process and thread synchronization mechanisms
o A good solution has no deadlock or starvation
Possibility of Deadlock
Possibility of Starvation
Review of Monitor Concept• Encapsulated data objects and procedures
(a.k.a. methods or functions) • Per-monitor lock enforces mutual exclusion • Only one thread may be executing in the monitor
at a time • Thread inside the monitor may reliquish the
monitor lock to wait for a condition • POSIX mutex and CVs designed to implement
monitors
Dining Philosophers Solution as Monitor
int update_state (int i) {
if (state[i] == HUNGRY
&& state[LEFT] != EATING
&& state[RIGHT] != EATING) {
state[i] = EATING;
pthread_cond_signal (&CV[i]);
}
return 0;
}
Dining Philosophers Solution as Monitor
voidchopsticks_take (int i) {
pthread_mutex_lock (&M);
state[i] = HUNGRY
update_state(i);
while (state[i] == HUNGRY)
pthread_cond_wait (&CV[i],&M);
pthread_mutex_unlock (&M);
}
voidchopsticks_put (int i) {
pthread_mutex_lock (&M);
state[i] = THINKING;
update_state (LEFT);
update_state (RIGHT);
pthread_mutex_unlock (&M);
}
The Complete Code
• Some of the code examples for dining philosophers include:
– chopsticks.h, the monitor interface – chopsticks0.c, the monitor implementation – philosophers_t.c, the main program
• The full code for this solution is in the indicated files.
Dining Philosopher Solution with Binary Semaphores,
void chopsticks_take (int i) { if (i == (NTHREADS - 1)) { lock (0); lock (NTHREADS - 1); } else { lock (i); lock ((i + 1) % NTHREADS); }}void chopsticks_ put (int i) { unlock (i); unlock ((i + 1) % NTHREADS);}
Unix Mutual Exclusion Mechanisms
• lockfiles (e.g., see open(...O_CREAT | O_EXCL...))
• System V semaphores (e.g., see sema_wait)
• POSIX semaphores (e.g., see sem_wait)
• File record locking (e.g., see flock(), lockf, and fcntl(...F_SETFL...))
• POSIX mutexes, with attribute PTHREAD_PROCESS_SHARED
Lockfile Implementation of Binary Semaphore
void lock (int i) { int fildes; while ((fildes = open (lockfilename[i], O_RDWR | O_CREAT |
O_EXCL, S_IRUSR | S_IWUSR))==-1) { if (errno != EEXIST) chopsticks_emergency_stop(); CHECK (usleep (100)); } close (fildes);} void unlock (int i) { CHECK (unlink (lockfilename[i]) == -1);}
Weaknesses of this Solution
• How do we choose the length of time to sleep? • What happens if it is too long? • What happens if it is too short? • What happens if the process dies while holding
a lock? – Keep all maskable signals masked while holding a
lockfile(see explanation of signals later)
– Time out when waiting for a lockfile, and then steal the lock
How good is this solution?• Is this solution subject to deadlock? If not,
why not?
• Is this solution subject to starvation? Why or why not?
• Which of the defects of this solution, if any, is due to the lockfile implementation, versus the way the binary semaphores are used in the solution?
Dining Philosopher Lockfile Solution Complete Code
• The code is included below
– chopsticks.h defines the interface – chopsticks1.c is the implementation – philosophers.c is a test driver main program
Variant Solution, using sigsuspend()
• For another solution
– chopsticks2.c is the alternate implementation
Counting Semaphores
Semaphores, versus Mutexes & CVs
• The POSIX thread synchronization objects, mutexes and condition variables, are a more recent invention than some other synchronization mechanisms. Using them, one can solve any problem that can be solved using other mechanisms. Here, we show how they can be used to implement one of the earliest and best known types of synchronization objects: semaphores.
Counting Semaphore (Stallings' version)
• A type of synchronization object • Atomically counts available resources, and waits for
resources to become available • Holds an integer value, called the count< which is initially
non-negative • Has an associated queue of waiting procesess • Operations:
– decrement, also known as P, down, and wait – s.count--;if (s.count < 0) { enqueue and block this process } – increment, also known as V, up, post, and signal – s.count++;if (s.count <= 0) {dequeue and unblock one process }
Implementation of Linux/POSIX Semaphore as Monitor,
using Mutex & CVtypdef struct counting_semaphore { pthread_mutex_t M; pthread_cond_t CV; int value;} sem_t;void semaphore_wait () { pthread_mutex_lock (&S.M); while (S.value == 0) pthread_cond_wait (&S.CV, &S.M); S.value--; pthread_mutex_unlock (&S.M);void semaphore_signal () { pthread_mutex_lock (&S.M); S.value++ ; if (S.value == 1) pthread_cond_signal (&S.CV); pthread_mutex_unlock (&S.M);}