Semaphores and Condition Variables

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

1 Interprocess Communication 1. Ways of passing information 2. Guarded critical activities (e.g. updating shared data) 3. Proper sequencing in case of.
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
Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong.
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:
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
Critical Sections and Race Conditions. Administrivia Install and build Nachos if you haven’t already.
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.
COSC 3407: Operating Systems Lecture 8: Semaphores, Monitors and Condition Variables.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts Amherst Operating Systems CMPSCI 377 Lecture.
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.
Semaphores, mutexes and condition variables. semaphores Two types – Binary – 0 or 1 – Counting 0 to n Wait – decrements > 0 forces a wait Post or signal.
Monitors CSCI 444/544 Operating Systems Fall 2008.
Semaphores CSCI 444/544 Operating Systems Fall 2008.
Jonathan Walpole Computer Science Portland State University
Race Conditions CS550 Operating Systems. Review So far, we have discussed Processes and Threads and talked about multithreading and MPI processes by example.
Computer Science 162 Discussion Section Week 3. Agenda Project 1 released! Locks, Semaphores, and condition variables Producer-consumer – Example (locks,
1 Race Conditions/Mutual Exclusion Segment of code of a process where a shared resource is accessed (changing global variables, writing files etc) is called.
CS510 Concurrent Systems Introduction to Concurrency.
Implementing Synchronization. Synchronization 101 Synchronization constrains the set of possible interleavings: Threads “agree” to stay out of each other’s.
6.3 Peterson’s Solution The two processes share two variables: Int turn; Boolean flag[2] The variable turn indicates whose turn it is to enter the critical.
Semaphores, Locks and Monitors By Samah Ibrahim And Dena Missak.
The Synchronization Toolbox. Mutual Exclusion Race conditions can be avoiding by ensuring mutual exclusion in critical sections. Critical sections are.
Operating Systems ECE344 Ashvin Goel ECE University of Toronto Mutual Exclusion.
Chapter 6 – Process Synchronisation (Pgs 225 – 267)
CS 3204 Operating Systems Godmar Back Lecture 7. 12/12/2015CS 3204 Fall Announcements Project 1 due on Sep 29, 11:59pm Reading: –Read carefully.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
Monitors and Blocking Synchronization Dalia Cohn Alperovich Based on “The Art of Multiprocessor Programming” by Herlihy & Shavit, chapter 8.
1 Previous Lecture Overview  semaphores provide the first high-level synchronization abstraction that is possible to implement efficiently in OS. This.
CS510 Concurrent Systems Jonathan Walpole. Introduction to Concurrency.
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
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.
CS 311/350/550 Semaphores. Semaphores – General Idea Allows two or more concurrent threads to coordinate through signaling/waiting Has four main operations.
Case Study: Pthread Synchronization Dr. Yingwu Zhu.
CS703 - Advanced Operating Systems
CPS110: Threads review and wrap up
CS703 – Advanced Operating Systems
COT 4600 Operating Systems Fall 2009
PARALLEL PROGRAM CHALLENGES
Process Synchronization
Monitors, Condition Variables, and Readers-Writers
CSE 120 Principles of Operating
More Threads and Synchronization
Chapter 5: Process Synchronization
Jonathan Walpole Computer Science Portland State University
Threading And Parallel Programming Constructs
Semaphore Originally called P() and V() wait (S) { while S <= 0
Lecture 2 Part 2 Process Synchronization
Critical section problem
Implementing Mutual Exclusion
CSE 451: Operating Systems Autumn Lecture 8 Semaphores and Monitors
Implementing Mutual Exclusion
Chapter 6: Synchronization Tools
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
CSE 153 Design of Operating Systems Winter 2019
CS333 Intro to Operating Systems
Chapter 6: Synchronization Tools
Monitors and Inter-Process Communication
Process/Thread Synchronization (Part 2)
Don Porter Portions courtesy Emmett Witchel
Review The Critical Section problem Peterson’s Algorithm
Presentation transcript:

Semaphores and Condition Variables

Locks Locks can be used to ensure mutual exclusion in conflicting critical sections. A lock is an object, a data item in memory. Methods: Lock::Acquire and Lock::Release. Threads pair calls to Acquire and Release. Acquire before entering a critical section. Release after leaving a critical section. Between Acquire/Release, the lock is held. Acquire does not return until any previous holder releases. Waiting locks can spin (a spinlock) or block (a mutex). A A R R

Nachos Thread States and Transitions running Thread::Yield (voluntary or involuntary) Thread::Sleep (voluntary) Scheduler::Run blocked ready Scheduler::ReadyToRun currentThread->Yield(); currentThread->Sleep();

Example: Per-Thread Counts and Total /* shared by all threads */ int counters[N]; int total; /* * Increment a counter by a specified value, and keep a running sum. * This is called repeatedly by each of N threads. * tid is a thread identifier unique across all threads. * value is just some arbitrary number. */ void TouchCount(int tid, int value) { counters[tid] += value; total += value; }

Reading Between the Lines of C /* counters[tid] += value; total += value; */ load counters, R1 ; load counters base load 8(SP), R2 ; load tid index shl R2, #2, R2 ; index = index * sizeof(int) add R1, R2, R1 ; compute index to array load 4(SP), R3 ; load value load (R1), R2 ; load counters[tid] add R2, R3, R2 ; counters[tid] += value store R2, (R1) ; store back to counters[tid] load total, R2 ; load total add R2, R3, R2 ; total += value store R2, total ; store total load add store load add store vulnerable between load and store of counters[tid]...but it’s non-shared. vulnerable between load and store of total, which is shared.

Using a Lock for the Counter/Sum Example int counters[N]; int total; Lock *lock; /* * Increment a counter by a specified value, and keep a running sum. */ void TouchCount(int tid, int value) { lock->Acquire(); counters[tid] += value; /* critical section code is atomic...*/ total += value; /* …as long as the lock is held */ lock->Release(); }

Portrait of a Lock in Motion

Example: A Bounded Resource int AllocateEntry() { int i; while (!FindFreeItem(&i)) block and wait for a free slot slot[i] = 1; /* grab free slot */ return(i); } void ReleaseEntry(int i) { slot[i] = 0; wakeup waiter, if any boolean FindFreeItem(int* index) { for (i = 0; i < TableSize; i++) if (slot[i] == 0) return it; return (FALSE);

Semaphores Mutexes are designed for mutual exclusion; they are not sufficient for higher-level synchronization needs. waiting for an event managing a resource with more than one instance Semaphores handle all of your synchronization needs with one elegant but confusing abstraction. an integer variable with special operations and properties “souped up” increment (Up or V) and decrement (Down or P) current value is the number of resource instances free to allocate atomic/implicit sleep when decrementing a zero semaphore atomic/implicit wakeup when incrementing

A Bounded Resource with a Counting Semaphore A semaphore for an N-way resource is called a counting semaphore. semaphore->Init(N); int AllocateEntry() { int i; semaphore->Down(); ASSERT(FindFreeItem(&i)); slot[i] = 1; return(i); } void ReleaseEntry(int i) { slot[i] = 0; semaphore->Up(); Passing a Down guarantees that a resource instance is reserved for the caller. Problems?

Semaphores as Mutexes Mutexes are often called binary semaphores. Semaphores must be initialized with a value representing the number of free resources: mutexes are a single-use resource. semapohore->Init(1); void Lock::Acquire() { semaphore->Down(); } void Lock::Release() semaphore->Up(); Down() to acquire a resource; blocks if no resource is available. Up() to release a resource; wakes up waiter if any. Up and Down are atomic. Mutexes are often called binary semaphores. However, “real” mutexes have additional constraints on their use.

Condition Variables Condition variables allow explicit event notification. much like a souped-up sleep/wakeup associated with a mutex to avoid sleep/wakeup races managing events using semaphores often demands more synchronization, which is “built in” condition variables alternative to counting semaphores for resource allocation “generally safer and more flexible than semaphores” Condition::Wait(Lock*) Condition:: Signal(Lock*) Condition::Broadcast(Lock*)

Using Condition Variables Condition *cv; Lock* cvMx; int waiter = 0; void await() { cvMx->Lock(); waiter = waiter + 1; /* “I’m sleeping” */ cv->Wait(cvMx); /* sleep */ cvMx->Unlock(); } void wakeup() { if (waiter) { cv->Signal(cvMx); waiter = waiter - 1; CvMx->Unlock(); Must hold lock when calling Wait. Wait atomically releases lock and sleeps until next Signal. Wait atomically reacquires lock before returning. Association with mutex allows threads to safely manage state related to the sleep/wakeup coordination (e.g., waiters count).

Bounded Resource with a Condition Variable Mutex* mx; Condition *cv; int AllocateEntry() { int i; mx->Acquire(); while(!FindFreeItem(&i)) cv.Wait(mx); slot[i] = 1; mx->Release(); return(i); } void ReleaseEntry(int i) { slot[i] = 0; cv->Signal(); “Loop before you leap.” Why is this Acquire needed?

Semaphores with Condition Variables void Down() { mutex->Acquire(); ASSERT(count >= 0); while(count == 0) condition->Wait(mutex); count = count - 1; mutex->Release(); } void Up() { count = count + 1; condition->Signal(mutex);

Semaphores vs. Condition Variables 1. Up differs from Signal in that: Signal has no effect if no thread is waiting on the condition. Condition variables are not variables! They have no value! Up has the same effect whether or not a thread is waiting. Semaphores retain a memory of all calls to Up. 2. Down differs from Wait in that: Down checks the condition and blocks only if necessary. no need to recheck the condition after returning from Down wait condition is defined internally, but is limited to a counter Wait is explicit: it does not check the condition, ever. condition is defined externally and protected by integrated mutex