Monitor Solutions to Classical Problems. 2 Announcements CS 415 Projects graded. –Mean 80.7, High 90 out of 90 CS 414 Homework due Monday.

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

Ch 7 B.
Chapter 6: Process Synchronization
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
CH7 discussion-review Mahmoud Alhabbash. Q1 What is a Race Condition? How could we prevent that? – Race condition is the situation where several processes.
1 Semaphores and Monitors CIS450 Winter 2003 Professor Jinhua Guo.
Operating Systems CMPSC 473 Mutual Exclusion Lecture 13: October 12, 2010 Instructor: Bhuvan Urgaonkar.
1 Semaphores and Monitors: High-level Synchronization Constructs.
COSC 3407: Operating Systems Lecture 8: Semaphores, Monitors and Condition Variables.
CS162 Operating Systems and Systems Programming Lecture 8 Readers-Writers Language Support for Synchronization February 13, 2006 Prof. Anthony D. Joseph.
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
Language Support for Concurrency. 2 Common programming errors Process i P(S) CS P(S) Process j V(S) CS V(S) Process k P(S) CS.
Synchronization: Monitors Hank Levy. 6/21/20152 Synchronization with Semaphores Semaphores can be used to solve any of the traditional synchronization.
Classical Synchronization Problems. Paradigms for Threads to Share Data We’ve looked at critical sections –Really, a form of locking –When one thread.
Synchronization Prof. Sirer CS 4410 Cornell University.
Language Support for Concurrency. 2 Announcements CS 415 project 1 due today! CS 414 homework 2 available due next week Midterm will be first week in.
Monitors CSCI 444/544 Operating Systems Fall 2008.
Semaphores CSCI 444/544 Operating Systems Fall 2008.
Synchronization..or: the trickiest bit of this course.
Race Conditions CS550 Operating Systems. Review So far, we have discussed Processes and Threads and talked about multithreading and MPI processes by example.
Classical Synchronization Problems. Announcements CS 414 grades and solutions available in CMS soon. –Average 74.3 –High of 95. –Score out of 100 pts.
Classical Synchronization Problems. Announcements CS 4410 #1 grades and solutions available in CMS soon. –Average 54, stddev 9.7 –High of 70. –Score out.
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Semaphores and Bounded Buffer Andy Wang Operating Systems COP 4610 / CGS 5765.
4061 Session 21 (4/3). Today Thread Synchronization –Condition Variables –Monitors –Read-Write Locks.
CSC321 Concurrent Programming: §5 Monitors 1 Section 5 Monitors.
Lecture 6: Synchronization (II) – Semaphores and Monitors
CSE 451: Operating Systems Winter 2012 Semaphores and Monitors Mark Zbikowski Gary Kimura.
1 Interprocess Communication (IPC) - Outline Problem: Race condition Solution: Mutual exclusion –Disabling interrupts; –Lock variables; –Strict alternation.
CSE 451: Operating Systems Winter 2014 Module 8 Semaphores, Condition Variables, and Monitors Mark Zbikowski Allen Center 476 ©
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Monitors and Blocking Synchronization Dalia Cohn Alperovich Based on “The Art of Multiprocessor Programming” by Herlihy & Shavit, chapter 8.
1 Condition Variables CS 241 Prof. Brighten Godfrey March 16, 2012 University of Illinois.
13/03/07Week 21 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Problems with Semaphores Used for 2 independent purposes –Mutual exclusion –Condition synchronization Hard to get right –Small mistake easily leads to.
COSC 3407: Operating Systems Lecture 9: Readers-Writers and Language Support for Synchronization.
IT 344: Operating Systems Winter 2008 Module 7 Semaphores and Monitors
1 Previous Lecture Overview  semaphores provide the first high-level synchronization abstraction that is possible to implement efficiently in OS. This.
Dining Philosophers & Monitors Questions answered in this lecture: How to synchronize dining philosophers? What are monitors and condition variables? What.
Synchronization..or: the trickiest bit of this course.
CS162 Section 2. True/False A thread needs to own a semaphore, meaning the thread has called semaphore.P(), before it can call semaphore.V() False: Any.
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
CS703 - Advanced Operating Systems
Synchronization Condition Variables and Monitors
CSE 120 Principles of Operating
CS703 – Advanced Operating Systems
Monitors, Condition Variables, and Readers-Writers
Day 13 Concurrency.
© 2013 Gribble, Lazowska, Levy, Zahorjan
Day 15 Concurrency.
CS510 Operating System Foundations
Prof. Sirer and Van Renesse CS 4410 Cornell University
Anthony D. Joseph and Ion Stoica
CSE 451: Operating Systems Autumn 2010 Module 8 Semaphores, Condition Variables, and Monitors Ed Lazowska Allen Center 570.
© 2013 Gribble, Lazowska, Levy, Zahorjan
CS703 - Advanced Operating Systems
CSE 451: Operating Systems Winter 2004 Module 7+ Monitor Supplement
CSE 451: Operating Systems Winter Module 8 Semaphores and Monitors
CSE 451: Operating Systems Autumn Lecture 8 Semaphores and Monitors
CSE 451: Operating Systems Autumn Lecture 7 Semaphores and Monitors
September 12, 2012 Ion Stoica CS162 Operating Systems and Systems Programming Lecture 5 Semaphores, Conditional Variables.
CSE 451: Operating Systems Autumn Module 8 Semaphores and Monitors
CSE 451: Operating Systems Winter Module 7 Semaphores and Monitors
CSE 451: Operating Systems Winter Module 7 Semaphores and Monitors
Chapter 7: Synchronization Examples
CSE 451: Operating Systems Winter Module 7 Semaphores and Monitors
Don Porter Portions courtesy Emmett Witchel
Review The Critical Section problem Peterson’s Algorithm
Presentation transcript:

Monitor Solutions to Classical Problems

2 Announcements CS 415 Projects graded. –Mean 80.7, High 90 out of 90 CS 414 Homework due Monday.

3 Goals for Today Continue with Synchronization Abstractions –Monitors and condition variables Producer Consumer with Monitors Readers-Writers problem and solution with Monitors

4 Review: Monitors Monitors represent the logic of the program –Wait if necessary –Signal when change something so any waiting threads can proceed Basic structure of monitor-based program: lock while (need to wait) { unlock condvar.wait(); lock } do something so no need to wait condvar.signal(); unlock Check and/or update state variables Wait if necessary Check and/or update state variables

5 Review: Producer-consumer with a bounded buffer Problem Definition –Producer puts things into a shared buffer (wait if full) –Consumer takes them out (wait if empty) –Use a fixed-size buffer between them to avoid lockstep Need to synchronize access to this buffer Correctness Constraints: –Consumer must wait for producer to fill buffers, if none full scheduling constraint –Producer must wait for consumer to empty buffers, if all full scheduling constraint –Only one thread can manipulate buffer queue at a time mutual exclusion Remember why we need mutual exclusion –Because computers are stupid General rule of thumb: Use a separate semaphore for each constraint –Semaphore not_empty; // consumer’s constraint –Semaphore not_full; // producer’s constraint –Semaphore mutex; // mutual exclusion

6 Producer-Consumer using Semaphores Init: Semaphore mutex = 1; /* for mutual exclusion*/ Semaphore not_full = N; /* number empty buf entries */ Semaphore not_empty = 0; /* number full buf entries */ any_t buf[N]; int tail = 0, head = 0; Producer void put(char ch) { P(not_full); P(mutex); // add ch to buffer buf[head%N] = ch; head++; V(mutex); V(not_empty); } Consumer char get() { P(not_empty); P(mutex); // remove ch from buffer ch = buf[tail%N]; tail++; V(mutex); V(not_full); return ch; }

7 Discussion about Bounded Buffer Solution Why asymmetry? –Producer does: P(not_full), V(not_empty) –Consumer does: P(not_empty), V(not_full) Is order of P’s important? –Yes! Can cause deadlock Is order of V’s important? –No, except that it might affect scheduling efficiency What if we have 2 producers or 2 consumers? –Do we need to change anything?

8 Review: Motivation for Monitors and Condition Variables Semaphores are a huge step up, but: –They are confusing because they are dual purpose: Both mutual exclusion and scheduling constraints Example: the fact that flipping of P’s in bounded buffer gives deadlock is not immediately obvious –Cleaner idea: Use locks for mutual exclusion and condition variables for scheduling constraints Definition: Monitor: a lock and zero or more condition variables for managing concurrent access to shared data –Use of Monitors is a programming paradigm –Some languages like Java provide monitors in the language The lock provides mutual exclusion to shared data: –Always acquire before accessing shared data structure –Always release after finishing with shared data –Lock initially free

9 Condition Variables How do we change the get() routine to wait until something is in buffer? –Could do this by keeping a count of the number of things on the queue (with semaphores), but error prone Condition Variable: a queue of threads waiting for something inside a critical section –Key idea: allow sleeping inside critical section by atomically releasing lock at time we go to sleep –Contrast to semaphores: Can’t wait inside critical section Operations: –Wait(&lock) : Atomically release lock and go to sleep. Re-acquire lock later, before returning. –Signal() : Wake up one waiter, if any –Broadcast() : Wake up all waiters Rule: Must hold lock when doing condition variable ops!

10 Producer Consumer using Monitors Monitor Producer_Consumer { any_t buf[N]; int n = 0, tail = 0, head = 0; condition not_empty, not_full; void put(char ch) { while(n == N) wait(not_full); buf[head%N] = ch; head++; n++; signal(not_empty); } char get() { while(n == 0) wait(not_empty); ch = buf[tail%N]; tail++; n--; signal(not_full); return ch; }

11 Reminders: Subtle aspects Notice that when a thread calls wait(), if it blocks it also automatically releases the monitor’s mutual exclusion lock This is an elegant solution to an issue seen with semaphores –Caller has mutual exclusion and wants to call P(not_empty)… but this call might block –If we just do the call, the solution deadlocks… –But if we first call V(mutex), we get a race condition!

12 Review: Mesa vs. Hoare monitors Need to be careful about precise definition of signal and wait. Consider a piece of our dequeue code: while (n==0) { wait(not_empty); // If nothing, sleep } ch = buf[tail%N]; // Get next item –Why didn’t we do this? if (n==0) { wait(not_empty); // If nothing, sleep } ch = buf[tail%N];// Get next item Answer: depends on the type of scheduling –Hoare-style (most textbooks): Signaler gives lock, CPU to waiter; waiter runs immediately Waiter gives up lock, processor back to signaler when it exits critical section or if it waits again –Mesa-style (Java, most real operating systems): Signaler keeps lock and processor Waiter placed on ready queue with no special priority Practically, need to check condition again after wait

13 Review: Can we construct Monitors from Semaphores? Locking aspect is easy: Just use a mutex Can we implement condition variables this way? Wait() { P(x_sem); } Signal() { V(x_sem); } –Doesn’t work: Wait() may sleep with lock held Does this work better? Wait() { V(mutex); // Release mutex lock P(x_sem); P(mutex); // Acquire mutex lock } Signal() { V(x_sem); } –No: Condition vars have no history, semaphores have history: What if thread signals and no one is waiting? NO-OP What if thread later waits? Thread Waits What if thread V’s and noone is waiting? Increment What if thread later does P? Decrement and continue

14 Construction of Monitors from Semaphores (con’t) Problem with previous try: –P and V are commutative – result is the same no matter what order they occur –Condition variables are NOT commutative Does this fix the problem? Wait(Lock lock) { V(mutex); // Release mutex lock P(x_sem); P(mutex); // Acquire mutex lock } Signal() { if semaphore queue is not empty V(x_sem); } –Not legal to look at contents of semaphore queue –There is a race condition – signaler can slip in after lock release and before waiter executes semaphore.P() It is actually possible to do this correctly –Complex solution for Hoare scheduling in book –Can you come up with simpler Mesa-scheduled solution?

15 Construction of Hoare Monitors using Semaphores For each procedure F: P(mutex); /* body of F */ if(next_count > 0) V(next); else V(mutex); Wait(){ x_count++; if(next_count > 0) V(next); else V(mutex); P(x_sem); x_count--; Signal(){ If(x_count > 0) { next_count++; V(x_sem); P(next); next_count--; }

16 Revisits: Readers/Writers Problem Motivation: Consider a shared database –Two classes of users: Readers – never modify database Writers – read and modify database –Is using a single lock on the whole database sufficient? Like to have many readers at the same time Only one writer at a time R R R W

17 Revisit: Readers/Writers Problem Correctness Constraints: –Readers can access database when no writers –Writers can access database when no readers or writers –Only one thread manipulates state variables at a time Basic structure of a solution: –Reader() Wait until no writers Access data base Check out – wake up a waiting writer –Writer() Wait until no active readers or writers Access database Check out – wake up waiting readers or writer –State variables (Protected by a lock called “lock”): int NReaders: Number of active readers; initially = 0 int WaitingReaders: Number of waiting readers; initially = 0 int NWriters: Number of active writers; initially = 0 int WaitingWriters: Number of waiting writers; initially = 0 Condition canRead = NIL Conditioin canWrite = NIL

18 Revisit: Readers-Writers Problem One issue we need to settle, to clarify problem statement. –Suppose that a writer is active and a mixture of readers and writers now shows up. Who should get in next? –Or suppose that a writer is waiting and an endless of stream of readers keeps showing up. Is it fair for them to become active? We’ll favor a kind of back-and-forth form of fairness: –Once a reader is waiting, readers will get in next. –If a writer is waiting, one writer will get in next.

19 Readers and Writers Monitor ReadersNWriters { int WaitingWriters, WaitingReaders,NReaders, NWriters; Condition CanRead, CanWrite; Void BeginWrite() { if(NWriters == 1 || NReaders > 0) { ++WaitingWriters; wait(CanWrite); --WaitingWriters; } NWriters = 1; } Void EndWrite() { NWriters = 0; if(WaitingReaders) Signal(CanRead); else Signal(CanWrite); } Void BeginRead() { if(NWriters == 1 || WaitingWriters > 0) { ++WaitingReaders; Wait(CanRead); --WaitingReaders; } ++NReaders; Signal(CanRead); } Void EndRead() { if(--NReaders == 0) Signal(CanWrite); }

20 Readers and Writers Monitor ReadersNWriters { int WaitingWriters, WaitingReaders,NReaders, NWriters; Condition CanRead, CanWrite; Void BeginWrite() { if(NWriters == 1 || NReaders > 0) { ++WaitingWriters; wait(CanWrite); --WaitingWriters; } NWriters = 1; } Void EndWrite() { NWriters = 0; if(WaitingReaders) Signal(CanRead); else Signal(CanWrite); } Void BeginRead() { if(NWriters == 1 || WaitingWriters > 0) { ++WaitingReaders; Wait(CanRead); --WaitingReaders; } ++NReaders; Signal(CanRead); } Void EndRead() { if(--NReaders == 0) Signal(CanWrite); }

21 Readers and Writers Monitor ReadersNWriters { int WaitingWriters, WaitingReaders,NReaders, NWriters; Condition CanRead, CanWrite; Void BeginWrite() { if(NWriters == 1 || NReaders > 0) { ++WaitingWriters; wait(CanWrite); --WaitingWriters; } NWriters = 1; } Void EndWrite() { NWriters = 0; if(WaitingReaders) Signal(CanRead); else Signal(CanWrite); } Void BeginRead() { if(NWriters == 1 || WaitingWriters > 0) { ++WaitingReaders; Wait(CanRead); --WaitingReaders; } ++NReaders; Signal(CanRead); } Void EndRead() { if(--NReaders == 0) Signal(CanWrite); }

22 Readers and Writers Monitor ReadersNWriters { int WaitingWriters, WaitingReaders,NReaders, NWriters; Condition CanRead, CanWrite; Void BeginWrite() { if(NWriters == 1 || NReaders > 0) { ++WaitingWriters; wait(CanWrite); --WaitingWriters; } NWriters = 1; } Void EndWrite() { NWriters = 0; if(WaitingReaders) Signal(CanRead); else Signal(CanWrite); } Void BeginRead() { if(NWriters == 1 || WaitingWriters > 0) { ++WaitingReaders; Wait(CanRead); --WaitingReaders; } ++NReaders; Signal(CanRead); } Void EndRead() { if(--NReaders == 0) Signal(CanWrite); }

23 Understanding the Solution A writer can enter if there are no other active writers and no readers are waiting

24 Readers and Writers Monitor ReadersNWriters { int WaitingWriters, WaitingReaders,NReaders, NWriters; Condition CanRead, CanWrite; Void BeginWrite() { if(NWriters == 1 || NReaders > 0) { ++WaitingWriters; wait(CanWrite); --WaitingWriters; } NWriters = 1; } Void EndWrite() { NWriters = 0; if(WaitingReaders) Signal(CanRead); else Signal(CanWrite); } Void BeginRead() { if(NWriters == 1 || WaitingWriters > 0) { ++WaitingReaders; Wait(CanRead); --WaitingReaders; } ++NReaders; Signal(CanRead); } Void EndRead() { if(--NReaders == 0) Signal(CanWrite); }

25 Understanding the Solution A reader can enter if –There are no writers active or waiting So we can have many readers active all at once Otherwise, a reader waits (maybe many do)

26 Readers and Writers Monitor ReadersNWriters { int WaitingWriters, WaitingReaders,NReaders, NWriters; Condition CanRead, CanWrite; Void BeginWrite() { if(NWriters == 1 || NReaders > 0) { ++WaitingWriters; wait(CanWrite); --WaitingWriters; } NWriters = 1; } Void EndWrite() { NWriters = 0; if(WaitingReaders) Signal(CanRead); else Signal(CanWrite); } Void BeginRead() { if(NWriters == 1 || WaitingWriters > 0) { ++WaitingReaders; Wait(CanRead); --WaitingReaders; } ++NReaders; Signal(CanRead); } Void EndRead() { if(--NReaders == 0) Signal(CanWrite); }

27 Understanding the Solution When a writer finishes, it checks to see if any readers are waiting –If so, it lets one of them enter –That one will let the next one enter, etc… Similarly, when a reader finishes, if it was the last reader, it lets a writer in (if any is there)

28 Readers and Writers Monitor ReadersNWriters { int WaitingWriters, WaitingReaders,NReaders, NWriters; Condition CanRead, CanWrite; Void BeginWrite() { if(NWriters == 1 || NReaders > 0) { ++WaitingWriters; wait(CanWrite); --WaitingWriters; } NWriters = 1; } Void EndWrite() { NWriters = 0; if(WaitingReaders) Signal(CanRead); else Signal(CanWrite); } Void BeginRead() { if(NWriters == 1 || WaitingWriters > 0) { ++WaitingReaders; Wait(CanRead); --WaitingReaders; } ++NReaders; Signal(CanRead); } Void EndRead() { if(--NReaders == 0) Signal(CanWrite); }

29 Understanding the Solution It wants to be fair –If a writer is waiting, readers queue up –If a reader (or another writer) is active or waiting, writers queue up –… this is mostly fair, although once it lets a reader in, it lets ALL waiting readers in all at once, even if some showed up “after” other waiting writers

30 Subtle aspects? The code is “simplified” because we know there can only be one writer at a time It also takes advantage of the fact that signal is a no-op if nobody is waiting Where do we see these ideas used? –In the “EndWrite” code (it signals CanWrite without checking for waiting writers) –In the EndRead code (same thing) –In StartRead (signals CanRead at the end)

31 Comparison with Semaphores With semaphores we never did have a “fair” solution of this sort –In fact it can be done, but the code is quite tricky Here the straightforward solution works in the desired way! –Monitors are less error-prone and also easier to understand –C# and Java primitives should typically be used in this manner, too…