D u k e S y s t e m s More Synchronization featuring Producer/Consumer with Semaphores Jeff Chase Duke University.

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

Synchronization NOTE to instructors: it is helpful to walk through an example such as readers/writers locks for illustrating the use of condition variables.
Ch 7 B.
Chapter 6: Process Synchronization
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Sleep/Wakeup and Condition Variables. Example: Await/Awake Consider a very simple use of sleep/wakeup to implement two new primitives: currentThread->Await()
Monitors and Semaphores. Annotated Condition Variable Example Condition *cv; Lock* cvMx; int waiter = 0; void await() { cvMx->Lock(); waiter = waiter.
1 Semaphores and Monitors: High-level Synchronization Constructs.
Operating Systems ECE344 Ding Yuan Synchronization (I) -- Critical region and lock Lecture 5: Synchronization (I) -- Critical region and lock.
Avishai Wool lecture Introduction to Systems Programming Lecture 4 Inter-Process / Inter-Thread Communication.
1 CS318 Project #3 Preemptive Kernel. 2 Continuing from Project 2 Project 2 involved: Context Switch Stack Manipulation Saving State Moving between threads,
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
Synchronization Principles. Race Conditions Race Conditions: An Example spooler directory out in 4 7 somefile.txt list.c scores.txt Process.
Concurrency: Mutual Exclusion, Synchronization, Deadlock, and Starvation in Representative Operating Systems.
Monitors CSCI 444/544 Operating Systems Fall 2008.
Semaphores CSCI 444/544 Operating Systems Fall 2008.
Race Conditions CS550 Operating Systems. Review So far, we have discussed Processes and Threads and talked about multithreading and MPI processes by example.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts, Amherst Operating Systems CMPSCI 377 Lecture.
Multithreaded Web Server.
CS510 Concurrent Systems Introduction to Concurrency.
D u k e S y s t e m s Asynchrony, Concurrency, and Threads Jeff Chase Duke University.
Semaphores and Bounded Buffer Andy Wang Operating Systems COP 4610 / CGS 5765.
1 Processes, Threads, Race Conditions & Deadlocks Operating Systems Review.
Starvation and Deadlock
Semaphores, Locks and Monitors By Samah Ibrahim And Dena Missak.
1 Announcements The fixing the bug part of Lab 4’s assignment 2 is now considered extra credit. Comments for the code should be on the parts you wrote.
4061 Session 21 (4/3). Today Thread Synchronization –Condition Variables –Monitors –Read-Write Locks.
Silberschatz, Galvin and Gagne  Operating System Concepts Chapter 7: Process Synchronization Background The Critical-Section Problem Synchronization.
1 Interprocess Communication (IPC) - Outline Problem: Race condition Solution: Mutual exclusion –Disabling interrupts; –Lock variables; –Strict alternation.
1 CMSC421: Principles of Operating Systems Nilanjan Banerjee Principles of Operating Systems Acknowledgments: Some of the slides are adapted from Prof.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
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:
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Computer Systems Principles Synchronization Emery Berger and Mark Corner University.
1 Previous Lecture Overview  semaphores provide the first high-level synchronization abstraction that is possible to implement efficiently in OS. This.
Operating Systems CMPSC 473 Signals, Introduction to mutual exclusion September 28, Lecture 9 Instructor: Bhuvan Urgaonkar.
Operating Systems COMP 4850/CISG 5550 Interprocess Communication, Part II Dr. James Money.
4.1 Introduction to Threads Overview Multithreading Models Thread Libraries Threading Issues Operating System Examples Windows XP Threads Linux Threads.
CSCI1600: Embedded and Real Time Software Lecture 17: Concurrent Programming Steven Reiss, Fall 2015.
CS510 Concurrent Systems Jonathan Walpole. Introduction to Concurrency.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Chapter 6: Process Synchronization.
© 2004, D. J. Foreman 1 Monitors and Inter-Process Communication.
D u k e S y s t e m s CPS 310 Threads and Concurrency: Topics Jeff Chase Duke University
© 2004, D. J. Foreman 1 Monitors and Inter-Process Communication.
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
CS703 - Advanced Operating Systems
CPS110: Reader-writer locks
CS703 – Advanced Operating Systems
Background on the need for Synchronization
Semaphores and Condition Variables
Chapter 5: Process Synchronization
Threads and Synchronization
Threads and Locks.
Threading And Parallel Programming Constructs
CSE 451 Autumn 2003 Section 3 October 16.
CSCI1600: Embedded and Real Time Software
CSE 451: Operating Systems Autumn Lecture 8 Semaphores and Monitors
Slides by Prof. Landon Cox and Vamsi Thummala
CSE 451: Operating Systems Autumn 2003 Lecture 7 Synchronization
CSE 451: Operating Systems Autumn 2005 Lecture 7 Synchronization
CSE 451: Operating Systems Winter 2003 Lecture 7 Synchronization
CSE 153 Design of Operating Systems Winter 19
CS333 Intro to Operating Systems
Chapter 6: Synchronization Tools
CSCI1600: Embedded and Real Time Software
CSE 451 Section 1/27/2000.
Monitors and Inter-Process Communication
Don Porter Portions courtesy Emmett Witchel
Presentation transcript:

D u k e S y s t e m s More Synchronization featuring Producer/Consumer with Semaphores Jeff Chase Duke University

Admin Shell lab demos Mission: get good at thread programming See notes and practice problems on the course web site. Lab 2 is out Midterm: Nov 14

A thread: review Program kernel stack user stack User TCB kernel TCB active ready or running blocked wait sleep wait wakeup signal When a thread is blocked its TCB is placed on a sleep queue of threads waiting for a specific wakeup event. This slide applies to the process abstraction too, or, more precisely, to the main thread of a process.

Resource Trajectory Graphs This RTG depicts a schedule within the space of possible schedules for a simple program of two threads sharing one core. Blue advances along the y-axis. Purple advances along the x-axis. The scheduler chooses the path (schedule, event order, or interleaving). The diagonal is an idealized parallel execution (two cores). Every schedule starts here. EXIT Every schedule ends here. context switch From the point of view of the program, the chosen path is nondeterministic.

Locking a critical section mx->Acquire(); x = x + 1; mx->Release(); mx->Acquire(); x = x + 1; mx->Release(); load add store load add store Holding a shared mutex prevents competing threads from entering a critical section protected by the shared mutex (monitor). At most one thread runs in the critical section at a time. A A R R  The threads may run the critical section in either order, but the schedule can never enter the grey region where both threads execute the section at the same time. X x=x+1

Monitor == mutex+CV P1() P2() P3() P4() state ready to enter waiting (blocked) wait() (enter) signal() At most one thread runs in the monitor at a time. wait() signal() A thread may wait in the monitor, allowing another thread to enter. A thread may signal in the monitor. Signal means: wake one waiting thread, if there is one, else do nothing. The awakened thread returns from its wait. A monitor has a mutex to protect shared state, a set of code sections that hold the mutex, and a condition variable with wait/signal primitives.

Using monitors/mutexes P1() P2() P3() P4() state ready to enter blocked wait() (enter) signal() Each monitor/mutex protects specific data structures (state) in the program. Threads hold the mutex when operating on that state. Threads hold the mutex when transitioning the structures from one consistent state to another, and restore the invariants before releasing the mutex. The state is consistent iff certain well-defined invariant conditions are true. A condition is a logical predicate over the state. Example invariant condition E.g.: suppose the state has a doubly linked list. Then for any element e either e.next is null or e.next.prev == e.

Java synchronization public class Object { void notify(); /* signal */ void notifyAll(); /* broadcast */ void wait(); void wait(long timeout); } public class PingPong extends Object { public synchronized void PingPong() { while(true) { notify(); wait(); } Every Java object has a monitor and condition variable built in. There is no separate mutex class or CV class. A thread must own an object’s monitor (“synchronized”) to call wait/notify, else the method raises an IllegalMonitorStateException. Wait(*) waits until the timeout elapses or another thread notifies.

Ping-Pong using a condition variable wait notify (signal) wait signal (notify) wait signal public synchronized void PingPong() { while(true) { notify(); wait(); } Interchangeable lingo synchronized == mutex == lock monitor == mutex+CV notify == signal Suppose blue gets the mutex first: its notify is a no-op. waiting for signal cannot acquire mutex

Condition variable operations wait (){ release lock put thread on wait queue go to sleep // after wake up acquire lock } signal (){ wakeup one waiter (if any) } broadcast (){ wakeup all waiters (if any) } Atomic Lock always held Lock usually held Lock always held

Example: event/request queue Incoming event queue worker loop Handle one event, blocking as necessary. When handler is complete, return to worker pool. We can synchronize an event queue with a mutex/CV pair. Protect the event queue data structure itself with the mutex. dispatch threads waiting on CV Workers wait on the CV for next event if the event queue is empty. Signal the CV when a new event arrives. This is a producer/consumer problem. handler

Producer-consumer problem  Pass elements through a bounded-size shared buffer  Producer puts in (must wait when full)  Consumer takes out (must wait when empty)  Synchronize access to buffer  Elements pass through in order  Examples  Unix pipes: cpp | cc1 | cc2 | as  Network packet queues  Server worker threads receiving requests  Feeding events to an event-driven program

Example: the soda/HFCS machine Vending machine (buffer) Soda drinker (consumer) Delivery person (producer)

Solving producer-consumer 1.What are the variables/shared state?  Soda machine buffer  Number of sodas in machine (≤ MaxSodas) 2.Locks?  1 to protect all shared state (sodaLock) 3.Mutual exclusion?  Only one thread can manipulate machine at a time 4.Ordering constraints?  Consumer must wait if machine is empty (CV hasSoda)  Producer must wait if machine is full (CV hasRoom)

Producer-consumer code producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock, hasRoom) } add one soda to machine signal (hasSoda) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasSoda) } take a soda from machine signal (hasRoom) unlock (sodaLock) } MxCV1MxCV2 CV1 CV2

Producer-consumer code producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock, hasRoom) } fill machine with soda broadcast(hasSoda) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasSoda) } take a soda from machine signal(hasRoom) unlock (sodaLock) } The signal should be a broadcast if the producer can produce more than one resource, and there are multiple consumers. lpcox slide edited by chase

Variations: looping producer  Producer  Infinite loop ok?  Why/why not?  Release lock in wait call producer () { lock (sodaLock) while (1) { while(numSodas==MaxSodas){ wait (sodaLock, hasRoom) } add soda to machine signal (hasSoda) } unlock (sodaLock) }

Variations: resting producer  Producer  Sleep ok?  Why/why not?  Shouldn’t hold locks during a slow operation producer () { lock (sodaLock) while (1) { sleep (1 hour) while(numSodas==MaxSodas){ wait (sodaLock, hasRoom) } add soda to machine signal (hasSoda) } unlock (sodaLock) }

Variations: one CV? producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock,hasRorS) } add one soda to machine signal(hasRorS) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasRorS) } take a soda from machine signal (hasRorS) unlock (sodaLock) } Two producers, two consumers: who consumes a signal? ProducerA and ConsumerB wait while ConsumerC signals? MxCVMxCV

Variations: one CV? producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock,hasRorS) } add one soda to machine signal (hasRorS) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasRorS) } take a soda from machine signal (hasRorS) unlock (sodaLock) } Is it possible to have a producer and consumer both waiting? max=1, cA and cB wait, pC adds/signals, pD waits, cA wakes

Variations: one CV? producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock,hasRorS) } add one soda to machine signal (hasRorS) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasRorS) } take a soda from machine signal (hasRorS) unlock (sodaLock) } How can we make the one CV solution work?

Variations: one CV? producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock,hasRorS) } add one soda to machine broadcast (hasRorS) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasRorS) } take a soda from machine broadcast (hasRorS) unlock (sodaLock) } Use broadcast instead of signal: safe but slow.

Broadcast vs signal  Can I always use broadcast instead of signal?  Yes, assuming threads recheck condition  And they should: “loop before you leap”!  Mesa semantics requires it anyway: another thread could get to the lock before wait returns.  Why might I use signal instead?  Efficiency (spurious wakeups)  May wakeup threads for no good reason  “Signal is just a performance hint”. lpcox slide edited by chase

Semaphore Now we introduce a new synchronization object type: semaphore. A semaphore is a hidden atomic integer counter with only increment (V) and decrement (P) operations. Decrement blocks iff the count is zero. Semaphores handle all of your synchronization needs with one elegant but confusing abstraction. V-Up P-Down int sem wait if (sem == 0) then

Example: binary semaphore A binary semaphore takes only values 0 and 1. It requires a usage constraint: the set of threads using the semaphore call P and V in strict alternation. – Never two V in a row. 1 0 P-Down V-Up wait P-Down wakeup on V

A mutex is a binary semaphore 1 0 P-Down V-Up wait P-Down wakeup on V V P PV Once a thread A completes its P, no other thread can P until A does a matching V. A mutex is just a binary semaphore with an initial value of 1, for which each thread calls P-V in strict pairs.

Semaphore synchronized void P() { if (s == 0) ………….; s = s - 1; ASSERT(s >= 0); } synchronized void V() { s = s + 1; ………. }

Semaphore synchronized void P() { while (s == 0) wait(); s = s - 1; ASSERT(s >= 0); } synchronized void V() { s = s + 1; signal(); } This code constitutes a proof that monitors (mutexes and condition variables) are at least as powerful as semaphores. Loop before you leap! Understand why the while is needed, and why an if is not good enough. Wait releases the monitor/mutex and blocks until a signal. Signal wakes up one waiter blocked in P, if there is one, else the signal has no effect: it is forgotten.

Synchronization objects OS kernel API offers multiple ways for threads to block and wait for some event. Details vary, but in general they wait for a specific event on some specific kernel object: a synchronization object. – I/O completion – wait*() for child process to exit – blocking read/write on a producer/consumer pipe – message arrival on a network channel – sleep queue for a mutex, CV, or semaphore, e.g., Linux “futex” – get next event/request (Android binder, UI thread) on a poll set – wait for a timer to expire

Windows synchronization objects This slide is just here to give a flavor of the synchronization objects In the Windows API, integrated with other system abstractions. They all enter a signaled state on some event, and revert to an unsignaled state after some reset condition. Threads block on an unsignaled object, and wake up when the object is signaled.

EventBarrier ebWait() ebComplete() ebSignal() controller eb.ebWait(); crossBridge(); eb.ebComplete(); …. eb.ebSignal(); …