1 / 29

CS 3214 Introduction to Computer Systems

CS 3214 Introduction to Computer Systems. Godmar Back. Lecture 19. Announcements. Read Chapter 13 (ignore stuff about file web servers for now) Exercise 10 due Nov 3 (today) Exercise 11 is out – very structured exercise Due Nov 12 (but should not take this long; don’t procrastinate)

abromberg
Download Presentation

CS 3214 Introduction to Computer Systems

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS 3214Introduction to Computer Systems Godmar Back Lecture 19

  2. Announcements • Read Chapter 13 • (ignore stuff about file web servers for now) • Exercise 10 due Nov 3 (today) • Exercise 11 is out – very structured exercise • Due Nov 12 (but should not take this long; don’t procrastinate) • Will give feedback on whether Project 3 meets minimum requirements before weekend • Will use the tests you provided • Project 4 out by Thursday CS 3214 Fall 2009

  3. Some of the following slides are taken with permission from Complete Powerpoint Lecture Notes forComputer Systems: A Programmer's Perspective (CS:APP) Randal E. Bryant and David R. O'Hallaron http://csapp.cs.cmu.edu/public/lectures.html Part 8 Threads and Processes CS 3214 Fall 2009

  4. Condition Variables - Intro • Besides (and perhaps more so) than semaphores, condition variables are another widely used form to implement ‘signaling’ kinds of coordination/synchronization • In POSIX Threads, Java, C# • Based on the concept of a Monitor • ADT that combines protected access to state and signaling • Confusing terminology alert: • Word ‘signal’ is overloaded 3 times • Semaphore signal (V(), “up”, “post”) • Monitor/Condition variable signal (“signal”, “notify”) • Unix signals • Word ‘wait’ is overloaded • Semaphore wait (P(), “down”) • Monitor/Condition variable wait • Unix wait() for child process CS 3214 Fall 2009

  5. Monitors • A monitor combines a set of shared variables & operations to access them • Think of a Java class with no public fields & all public methods carrying the attribute ‘synchronized’ • A monitor provides implicit synchronization (only one thread can access private variables simultaneously) • Single lock is used to ensure all code associated with monitor is within critical section • A monitor provides a general signaling facility • Wait/Signal pattern (similar to, but different from semaphores) • May declare & maintain multiple signaling queues CS 3214 Fall 2009

  6. Monitors (cont’d) • Classic monitors are embedded in programming languages • Invented by Hoare & Brinch-Hansen 1972/73 • First used in Mesa/Cedar System @ Xerox PARC 1978 • Adapted version available in Java/C# • (Classic) Monitors are safer than semaphores • can’t forget to lock data – compiler checks this • In contemporary C, monitors are a synchronization pattern that is achieved using locks & condition variables • Helps to understand monitor abstraction to use it correctly CS 3214 Fall 2009

  7. Infinite Buffer w/ Monitor monitor buffer { /* implied: struct lock mlock;*/ private: char buffer[]; int head, tail; public: produce(item); item consume(); } buffer::produce(item i) { /* try { lock_acquire(&mlock); */ buffer[head++] = i; /* } finally {lock_release(&mlock);} */ } buffer::consume() { /* try { lock_acquire(&mlock); */ return buffer[tail++]; /* } finally {lock_release(&mlock);} */ } • Monitors provide implicit protection for their internal variables • Still need to add the signaling part CS 3214 Fall 2009

  8. Condition Variables • Used by a monitor for signaling a condition • a general (programmer-defined) condition, not just integer increment as with semaphores • Somewhat weird: the condition is actually not stored in the variable – it’s typically some boolean predicate of monitor variables, e.g. “buffer.size > 0” • the condition variable itself is better thought of as a signaling queue • Monitor can have more than one condition variable • Three operations: • Wait(): leave monitor, wait for condition to be signaled, reenter monitor • Signal(): signal one thread waiting on condition • Broadcast(): signal all threads waiting on condition CS 3214 Fall 2009

  9. Enter Region of mutual exclusion Wait Signal Wait Signal Exit Condition Variables as Queues • A condition variable’s state is just a queue of waiters: • Wait(): adds current thread to (end of queue) & block • Signal(): pick one thread from queue & unblock it • Broadcast(): unblock all threads Note on style: best practice is to leave monitor only once, and near the procedure’s entry. CS 3214 Fall 2009

  10. Bounded Buffer w/ Monitor monitor buffer { condition items_avail; condition slots_avail; private: char buffer[]; int head, tail; public: produce(item); item consume(); } buffer::produce(item i) { while ((tail+1–head)%CAPACITY==0) slots_avail.wait(); buffer[head++] = i; items_avail.signal(); } buffer::consume() { while (head == tail) items_avail.wait(); item i = buffer[tail++]; slots_avail.signal(); return i; } CS 3214 Fall 2009

  11. Bounded Buffer w/ Monitor monitor buffer { condition items_avail; condition slots_avail; private: char buffer[]; int head, tail; public: produce(item); item consume(); } buffer::produce(item i) { while ((tail+1–head)%CAPACITY==0) slots_avail.wait(); buffer[head++] = i; items_avail.signal(); } buffer::consume() { while (head == tail) items_avail.wait(); item i = buffer[tail++]; slots_avail.signal(); return i; } Q1.: How is lost update problem avoided? lock_release(&mlock); block_on(items_avail); lock_acquire(&mlock); Q2.: Why while() and not if()? CS 3214 Fall 2009

  12. cond_signal semantics • cond_signal keeps lock, so it leaves signaling thread in monitor • waiter is made READY, but can’t enter until signaler gives up lock • There is no guarantee whether signaled thread will enter monitor next or some other thread will (who may be already waiting!) • so must always use “while()” when checking condition – cannot assume that condition set by signaling thread will still hold when monitor is reentered by signaled thread • This semantics is also referred to as “Mesa-Style” after the system in which it was first used • POSIX Threads, Java, and C# use this semantics CS 3214 Fall 2009

  13. Condition Variables Signals are lost if nobody’s on the queue (e.g., nothing happens) Wait() always blocks Semaphores Signals (calls to V() or sem_post()) are remembered even if nobody’s current waiting Wait (e.g., P() or sem_wait()) may or may not block Condition Variables vs. Semaphores CS 3214 Fall 2009

  14. Monitors in C • POSIX Threads as well as many custom environments • No compiler support, must do it manually • must declare locks & condition vars • must call pthread_mutex_lock/unlock when entering & leaving the monitor • must use pthread_cond_wait/pthread_cond_signal to wait for/signal condition • Note: pthread_cond_wait(&c, &m) takes monitor lock as parameter • necessary so monitor can be left & reentered without losing signals • pthread_cond_signal() does not • leaving room for programmer error! CS 3214 Fall 2009

  15. synchronized block means enter monitor execute block leave monitor wait()/notify() use condition variable associated with receiver Every object in Java can function as a condition variable (just like it can function as a lock) More restrictive than Pthreads/C which allow multiple condition variables (signaling conditions) to be used in connection with a lock protecting state Monitors in Java class buffer { private char buffer[]; private int head, tail; public synchronized produce(item i) { while (buffer_full()) this.wait(); buffer[head++] = i; this.notifyAll(); } public synchronized item consume() { while (buffer_empty()) this.wait(); i = buffer[tail++]; this.notifyAll(); return ; } } CS 3214 Fall 2009

  16. Previous slide (bounded buffer) is actually an example of where Java’s built-in monitors suck Needed “notifyAll()” to make sure one at least one of the right kind of threads was woken up Unacceptably inefficient Use java.util.concurrent.- locks.Condition instead in case where multiple condition queues are needed import java.util.concurrent.locks.*; class buffer { private ReentrantLockmonitorlock = new ReentrantLock(); private Condition items_available = monitorlock.newCondition(); private Condition slots_available = monitorlock.newCondition(); public /* NO SYNCHRONIZED here */ void produce(item i) { monitorlock.lock(); try { while (buffer_full()) slots_available.await(); buffer[head++] = i; items_available.signal(); } finally { monitorlock.unlock(); } } /* consume analogous */ } Monitors in Java, Take 2 CS 3214 Fall 2009

  17. A ReadWrite Lock Implementation struct lock mlock; // protects rdrs & wrtrs int readers = 0, writers = 0; structcondvarcanread, canwrite; void read_lock_acquire() { lock_acquire(&mlock); while (writers > 0) cond_wait(&canread, &mlock); readers++; lock_release(&mlock); } void read_lock_release() { lock_acquire(&mlock); if (--readers == 0) cond_signal(&canwrite); lock_release(&mlock); } void write_lock_acquire() { lock_acquire(&mlock); while (readers > 0 || writers > 0) cond_wait(&canwrite, &mlock); writers++; lock_release(&mlock); } void write_lock_release() { lock_acquire(&mlock); writers--; ASSERT(writers == 0); cond_broadcast(&canread); cond_signal(&canwrite); lock_release(&mlock); } Note: this is a naïve implementation that may lead to livelock – no guarantees a reader or writer ever enters the locked section even if every threads eventually leaves it CS 3214 Fall 2009

  18. Summary • Semaphores & Condition Variables provide signaling facilities • Condition variables are loosely based on “monitor” concept • Java/C# provide syntactic sugar • Semaphores have “memory” • But require that # of signals matches # of waits • Good for rendez-vous, precedence constraints – if problem lends itself to semaphore, use one • Always use idiomatic “while (!cond) *_wait()” pattern when using condition variables (in C) or Object.wait() (in Java) CS 3214 Fall 2009

  19. Race Detection Tools • A number of tools help to detect race conditions (Helgrind, Intel Thread Checker) • Dynamic analysis tools • Typically based one or both of these approaches: • Locksets: detect if no lock is consistently held when a given variable x is accessed • “Happens-before” relationship: (intuition) if we can’t prove that access A must happen before B due to the synchronization the programmer used, then it’s a race; example: • All accesses before a thread is started “happen before” all accesses by a thread; and these accesses “happen before” all accesses done after the thread is joined • Typically do not detect atomicity violations CS 3214 Fall 2009

  20. A situation in which two or more threads or processes are blocked and cannot proceed “blocked” either on a resource request that can’t be granted, or waiting for an event that won’t occur Possible causes: resource-related or communication-related Cannot easily back out Deadlock (Definition) CS 3214 Fall 2009

  21. A B Thread 1 Thread 2 Resource Deadlock Canonical Example pthread_mutex_t A; pthread_mutex_t B; … pthread_mutex_lock(&A); pthread_mutex_lock(&B); … pthread_mutex_unlock(&B); pthread_mutex_unlock(&A); pthread_mutex_lock(&B); pthread_mutex_lock(&A); … pthread_mutex_unlock(&A); pthread_mutex_unlock(&B); CS 3214 Fall 2009

  22. Using Lock Ordering to Avoid Deadlock • acquire locks in same order void transferTo(account *this, account *that, int amount) { if (this < that) { pthread_mutex_lock(&this->lock); pthread_mutex_lock(&that->lock); } else { pthread_mutex_lock(&that->lock); pthread_mutex_lock(&this->lock); } /* rest of function */ } Tricky in Java when synchronized is used: System.identityHashcode provides ordering of arbitrary objects CS 3214 Fall 2009

  23. Deadlocks, more formally • 4 necessary conditions • Exclusive Access • Hold and Wait • No Preemption • Circular Wait • Aka Coffman conditions • Note that cond 1-3 represent things that are normally desirable or required • Strategies involve • Detect & break deadlocks • Prevent • Avoid CS 3214 Fall 2009

  24. Resource Allocation Graph R → P Assignment P → R Request R1 R3 P1 P2 P3 P4 R2 R4 Deadlocks Detection • Uses Resource AllocationGraph • For single-item resourcescycle in this graph is necessary & sufficient for resource deadlock to exist • Some systems have deadlock detection built-in • But usually an option that must be turned on CS 3214 Fall 2009

  25. Deadlock Recovery • Can attempt to revoke resources, kill some participants, or (worst case) kill all participants to break cycle CS 3214 Fall 2009

  26. Deadlock Prevention • Idea: remove a necessary condition • C1: (do not require) exclusive access • C2: (don’t) hold and (then) wait • C3: (allow) preemption/revocation • C4: (don’t) create cycles: lock ordering! • Deadlock is tricky because it’s not always clear/possible how to remove or eliminate these conditions, particularly C4 • Distinct from “Deadlock Avoidance” • Well studied, but rarely used technique in which necessary conditions aren’t removed, but resource allocations are managed in a way that avoids deadlock CS 3214 Fall 2009

  27. Deadlock vs. Starvation vs. Livelock • Deadlock: • No matter which policy the scheduler chooses, there is no possible way for processes to make forward progress • Starvation: • There is a possible way in which threads can make possible forward progress, but the scheduler doesn’t choose it • Example: strict priority scheduler will never scheduler lower priority threads as long as higher-priority thread is READY • Example: naïve reader/writer lock: starvation may occur by “bad luck” • Livelock: • Threads are continually engaged in tasks that prevent them from making progress on their actual goals, such as reattempting to acquire locks, or responding to each other’s signals CS 3214 Fall 2009

  28. Informal uses of term `deadlock’ • 4 Coffman conditions apply specifically to deadlock with definable resources • Term deadlock is sometimes informally used to also describe situations in which not all 4 criteria apply • See interesting discussion in Levine 2003, Defining Deadlock • Consider: When two trains approach each other at a crossing, both shall come to a full stop and neither shall start up again until the other has gone. • Does it meet the 4 conditions? • However, even under informal/extended view, not all “lack of visible progress” situations can reasonably be called deadlocked • e.g., an idle system is not usually considered deadlocked CS 3214 Fall 2009

  29. Summary • Deadlock: • 4 necessary conditions: mutual exclusion, hold-and-wait, no preemption, circular wait • Strategies to deal with: • Prevention: remove one of 4 necessary conditions • Detect & recover • Avoidance: if you can’t do that, avoid deadlock by being conservative CS 3214 Fall 2009

More Related