CS5460: Operating Systems Lecture 11: Deadlock (Chapter 7) CS 5460: Operating Systems
Dining Philosophers Problem Five Philosophers sitting around a table One fork between each pair of philosophers Rule: Need two forks to eat Rule: Can only acquire one fork at a time Rule: Once fork acquired, not relinquished until done When done eating, relinquish both forks CS 5460: Operating Systems
Dining Philosophers Problem Class Philosophers { Let’s solve this interactively … private: semaphore fork[5]; – Hint: Use provided semaphores public: void Eat(int id); – Avoid deadlock } – Avoid unfairness – Does order or fork acquisition Philosophers::Eat( int mypid ) { matter? entry: // Acquire “ my ” forks EAT: // Eat spaghetti exit: // Relinquish “ my ” forks } CS 5460: Operating Systems
Dining Philosophers Solution v1 Let’s solve this interactively Class Philosophers { – Hint: Use provided semaphores private: semaphore fork[5]; – Does order matter? public: void Eat(int id); } Philosophers::Eat( int mypid ) { entry: // Acquire “ my ” forks P( fork[mypid] ); P( fork[(mypid+1)%5] ); EAT: // Eat spaghetti exit: // Relinquish “ my ” forks V( fork[mypid+1]%5 ); V( fork[mypid] ); } CS 5460: Operating Systems
Problem with v1 Solution… Let’s solve this interactively Class Philosophers { – Hint: Use provided semaphores private: semaphore fork[5]; – Does order matter? public: void Eat(int id); » Yes! } Philosophers::Eat( int mypid ) { entry: // Acquire “ my ” forks P( fork[mypid] ); P( fork[(mypid+1)%5] ); EAT: // Eat spaghetti exit: // Relinquish “ my ” forks V( fork[mypid+1]%5 ); V( fork[mypid] ); } CS 5460: Operating Systems
Dining Philosophers Solution v2 Class Philosophers { Let’s solve this interactively private: semaphore fork[5]; – Hint: Use provided semaphores public: void Eat(int id); – Does this solve the deadlock } problem? – Does it work overall? Philosophers::Eat( int mypid ) { entry: if (mypid==0) return; P( fork[mypid] ); P( fork[(mypid+1)%5] ); EAT: // Eat spaghetti exit: V( fork[mypid+1]%5 ); V( fork[mypid] ); } CS 5460: Operating Systems
Dining Philosophers Solution v3 Class Philosophers { Let’s solve this interactively private: semaphore fork[5]; – Hint: Use provided semaphores public: void Eat(int id); – Does this solve problem? } » Yes … why? – Does order of release Philosophers::Eat( int mypid ) { matter? entry: if (mypid&1) { P( fork[mypid] ); P( fork[(mypid+1)%5] ); } else { P( fork[(mypid+1)%5] ); P( fork[mypid] ); } EAT: // Eat spaghetti exit: V( fork[mypid+1]%5 ); V( fork[mypid] ); } CS 5460: Operating Systems
More Solutions? CS 5460: Operating Systems
Deadlock Deadlock: Two or more threads are waiting on events that only those threads can generate – Computers don’t see the “ big picture ” needed to break the stalemate – Hard to handle automatically à à lots of theory, little practice Livelock: Thread blocked indefinitely by other thread(s) using a resource Livelock naturally goes away when system load decreases Deadlock does not go away by itself CS 5460: Operating Systems
CS 5460: Operating Systems
Required Conditions for Deadlock Mutual exclusion: Resources cannot be shared Hold and wait: A thread is both holding a resource and waiting on another resource to become free No preemption: Once a thread gets a resource, it cannot be taken away Circular wait: There is a cycle in the graph of who has what and who wants what … Thread_A: Thread_B: A B P(X); P(Y); X Y P(Y); P(X); CS 5460: Operating Systems
What is smallest number of threads needed to deadlock? CS 5460: Operating Systems
Dining Philosophers Solution Class Philosophers { Removing deadlock … private: semaphore fork[5]; public: void Eat(int id); – Which condition did we eliminate } in V2.0 solution? – How? Philosophers::Eat( int mypid ) { entry: if (mypid&1) { P( fork[mypid] ); P( fork[(mypid+1)%5] ); } else { P( fork[(mypid+1)%5] ); P( fork[mypid] ); } < Eat spaghetti > exit: V( fork[mypid+1]%5 ); V( fork[mypid] ); } CS 5460: Operating Systems
Dealing with Deadlock Deadlock ignorance – Why worry? Deadlock detection – Figure out when deadlock has occurred and “ deal with it ” » Figuring it out à à mildly difficult » Dealing with it à à often messy, may need to reboot Deadlock avoidance – Reject resource requests that might lead to deadlock Deadlock prevention – Use “ rules ” that make it impossible for all four conditions to hold CS 5460: Operating Systems
Deadlock Detection Resource allocation graph – Resources {r 1 , … , r m } r 1 r 2 – Threads {t 1 , … , t m } – Edges: » t i à à r j : t i wants r j t 1 t 3 t 4 t 2 » r j à à t i : r j allocated to t i Acyclic à à no deadlocks Cyclic à à deadlock r 5 r 3 r 4 Cycle detection – Several known algorithms – O(n 2 ), n = |T| + |R| Alternative approach: Wait for someone to hold a resource for way to long, then decide that deadlock has occurred CS 5460: Operating Systems
Deadlock Detection Periodically scan for deadlocks X When to scan: – Just before granting resources? – Whenever resources unavailable? – Fixed intervals? – When CPU utilization drops? – When thread not runnable for extended period of time? How to recover? – Terminate threads – Break locks – Invoke exception handlers – Create more resources – Reboot – … CS 5460: Operating Systems
Deadlock Avoidance Idea: – Run version of deadlock detection algorithm in resource allocator – Add “ claim ” edges to resources threads may request – A cycle in extended graph à à unsafe state à à may lead to deadlock – Deny allocations that result in unsafe states » Claim edge converted to request edge » Thread blocks until request can be safely satisfied r 1 r 2 Do you think this is used often? t 1 t 3 t 4 t 2 Why or why not? r 5 r 3 r 4 CS 5460: Operating Systems
Deadlock Prevention Prevent deadlock by ensuring at least one necessary condition cannot occur: – Mutual exclusion: Make resources shared (hard in practice) – Hold and wait: Several possibilities … » Never require more than one resource at a time » Require all resources to be acquired at once » Require current resources to be freed and reacquired if need more – No preemption: Make resources preemptible » Resource allocator releases held resources when new request arrives » Threads must be coded to expect this behavior – Circular wait » Strictly order resources à à must acquire in increasing order » Requires global system knowledge CS 5460: Operating Systems
Distributed Deadlock We’ve been talking about deadlocked threads / processes on a single machine Of course, deadlock can also occur across machines Distributed deadlock can be hard to deal with – Hard to get a good picture of the global system – May be hard to take coordinated action – Distributed systems are often in a state of partial failure CS 5460: Operating Systems
When do you have to worry about deadlock? Any time you write code that acquires more than one lock CS 5460: Operating Systems • Lecture 12
A Few Approaches in Practice User mode code on Linux – Helgrind – a Valgrind plugin that dynamically checks for circular wait Linux kernel – Lock validator – dynamically checks for circular wait Solaris kernel – Has a strict lock ordering – “Lock lint” tool performs static analysis Windows thread pool – Create more threads if stuck Linux CPU scheduler – Avoid starving any thread CS 5460: Operating Systems
Important From Today Four conditions required for deadlock to occur: – Mutual exclusion – Hold and wait – No resource pre-emption – Circular wait Four techniques for handling deadlock – Prevention: Design rules so one condition cannot occur – Avoidance: Dynamically deny “ unsafe ” requests – Detection and recovery: Let it happen, notice it, and fix it – Ignore: Do nothing, hope it does not happen, reboot often CS 5460: Operating Systems
Questions? CS 5460: Operating Systems
Recommend
More recommend