Condition Variables & Semaphores

Similar documents
Concurrency: Signaling and Condition Variables

Announcements. Class feedback for mid-course evaluations Receive about survey to fill out until this Friday

Condition Variables. Jinkyu Jeong Computer Systems Laboratory Sungkyunkwan University

[537] Locks and Condition Variables. Tyler Harter

CS 471 Operating Systems. Yue Cheng. George Mason University Fall 2017

[537] Semaphores. Tyler Harter

Lecture 13 Condition Variables

Condition Variables. parent: begin child parent: end

Implementing Locks. Nima Honarmand (Based on slides by Prof. Andrea Arpaci-Dusseau)

Review: Processes. A process is an instance of a running program. POSIX Thread APIs:

CS 537: Introduction to Operating Systems Fall 2015: Midterm Exam #2 SOLUTIONS

Condition Variables. Dongkun Shin, SKKU

Operating System Labs. Yuanbin Wu

Condition Variables. Dongkun Shin, SKKU

Systèmes d Exploitation Avancés

Condition Variables. Figure 29.1: A Parent Waiting For Its Child

CS 162 Operating Systems and Systems Programming Professor: Anthony D. Joseph Spring Lecture 8: Semaphores, Monitors, & Condition Variables

Synchronising Threads

TCSS 422: OPERATING SYSTEMS

30. Condition Variables

1. Introduction. 2. Project Submission and Deliverables

Concurrency, Thread. Dongkun Shin, SKKU

CMSC421: Principles of Operating Systems

Operating Systems. Thread Synchronization Primitives. Thomas Ropars.

Recap: Thread. What is it? What does it need (thread private)? What for? How to implement? Independent flow of control. Stack

Synchronization II. q Condition Variables q Semaphores and monitors q Some classical problems q Next time: Deadlocks

Thread. Disclaimer: some slides are adopted from the book authors slides with permission 1

Condition Variables CS 241. Prof. Brighten Godfrey. March 16, University of Illinois

Locks and semaphores. Johan Montelius KTH

recap, what s the problem Locks and semaphores Total Store Order Peterson s algorithm Johan Montelius 0 0 a = 1 b = 1 read b read a

C09: Process Synchronization

Semaphore. Originally called P() and V() wait (S) { while S <= 0 ; // no-op S--; } signal (S) { S++; }

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

Locks and semaphores. Johan Montelius KTH

Synchronization II. Today. ! Condition Variables! Semaphores! Monitors! and some classical problems Next time. ! Deadlocks

Operating Systems CMPSCI 377 Spring Mark Corner University of Massachusetts Amherst

EECS 482 Introduction to Operating Systems

More Types of Synchronization 11/29/16

Operating systems and concurrency (B08)

CSE 451: Operating Systems Winter Lecture 7 Synchronization. Steve Gribble. Synchronization. Threads cooperate in multithreaded programs

Synchronization 1. Synchronization

Chapter 6: Process Synchronization

CS533 Concepts of Operating Systems. Jonathan Walpole

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

CMSC421: Principles of Operating Systems

Synchronization. Disclaimer: some slides are adopted from the book authors slides with permission 1

Figure 30.1: A Parent Waiting For Its Child What we would like to see here is the following output:

Implementing Mutual Exclusion. Sarah Diesburg Operating Systems CS 3430

Lecture 9: Midterm Review

CS 31: Intro to Systems Misc. Threading. Kevin Webb Swarthmore College December 6, 2018

Introduction to PThreads and Basic Synchronization

POSIX Threads: a first step toward parallel programming. George Bosilca

CSE 120 Principles of Operating Systems Spring 2016

Lecture 5 Threads and Pthreads II

Administrivia. Review: Thread package API. Program B. Program A. Program C. Correct answers. Please ask questions on Google group

Operating Systems. Lecture 4 - Concurrency and Synchronization. Master of Computer Science PUF - Hồ Chí Minh 2016/2017

PROCESS SYNCHRONIZATION

Introduction to Operating Systems Prof. Chester Rebeiro Department of Computer Science and Engineering Indian Institute of Technology, Madras

CSE 451: Operating Systems Winter Lecture 7 Synchronization. Hank Levy 412 Sieg Hall

Background. The Critical-Section Problem Synchronisation Hardware Inefficient Spinning Semaphores Semaphore Examples Scheduling.

EECS 482 Introduction to Operating Systems

CS 153 Design of Operating Systems Winter 2016

Synchroniza+on II COMS W4118

CS 153 Design of Operating Systems Winter 2016

W4118 Operating Systems. Instructor: Junfeng Yang

Synchronization I. Jo, Heeseung

SYNCHRONIZATION M O D E R N O P E R A T I N G S Y S T E M S R E A D 2. 3 E X C E P T A N D S P R I N G 2018

Synchronization and Semaphores. Copyright : University of Illinois CS 241 Staff 1

CS 318 Principles of Operating Systems

Lecture 8: September 30

Process & Thread Management II. Queues. Sleep() and Sleep Queues CIS 657

Process & Thread Management II CIS 657

Page 1. Goals for Today" Atomic Read-Modify-Write instructions" Examples of Read-Modify-Write "

TCSS 422: OPERATING SYSTEMS

Lecture 4. Threads vs. Processes. fork() Threads. Pthreads. Threads in C. Thread Programming January 21, 2005

Solving the Producer Consumer Problem with PThreads

Locks. Dongkun Shin, SKKU

Synchronization 1. Synchronization

Background. Old Producer Process Code. Improving the Bounded Buffer. Old Consumer Process Code

Summary Semaphores. Passing the Baton any await statement. Synchronisation code not linked to the data

Review: Thread package API

[537] Concurrency Bugs. Tyler Harter

CS 470 Spring Mike Lam, Professor. Semaphores and Conditions

Dealing with Issues for Interprocess Communication

Today: Synchronization. Recap: Synchronization

Semaphores. Jinkyu Jeong Computer Systems Laboratory Sungkyunkwan University

Reminder from last time

CPS 310 first midterm exam, 10/6/2014

Chap. 6 Part 1. CIS*3090 Fall Fall 2016 CIS*3090 Parallel Programming 1

Student: Yu Cheng (Jade) ICS 412 Homework #3 October 07, Explain why a spin-lock is not a good idea on a single processor, single machine.

CS 105, Spring 2015 Ring Buffer

Last Class: CPU Scheduling! Adjusting Priorities in MLFQ!

Review: Thread package API

Last Class: Synchronization

Real Time Operating Systems and Middleware

CSE 153 Design of Operating Systems

POSIX Threads: a first step toward parallel programming. George Bosilca

CS-537: Midterm Exam (Spring 2001)

Warm-up question (CS 261 review) What is the primary difference between processes and threads from a developer s perspective?

Operating Systems, Assignment 2 Threads and Synchronization

Transcription:

Condition Variables & Semaphores Nima Honarmand (Based on slides by Prof. Andrea Arpaci-Dusseau)

Review: Concurrency Objectives Mutual Exclusion A & B don t run at the same time Solved using locks Ordering B runs after A does something Solved using condition variables

Example 1: Thread Join pthread_t p1, p2; // create child threads pthread_create(&p1, NULL, mythread, "A"); pthread_create(&p2, NULL, mythread, "B"); // join waits for the child threads to finish thr_join(p1, NULL); thr_join(p2, NULL); how to implement thr_join()? return 0;

Waiting for an Event Parent thread has to wait until child terminates Option 1: spin until that happens Waste of CPU time Option 2: wait (sleep) in a queue until that happens Better use of CPU time Similar to the idea in queue-based lock of previous lecture Child thread will signal the parent to wake up before its termination

Generalizing Option 2 Condition Variable: queue of waiting threads with two basic operations B waits for a signal on cv before running cond_wait(cv, ) A sends signal to cv to wake-up one waiting thread cond_signal(cv, )

Thread Join: Attempt 1 Parent void thr_join() { cond_wait(&c); Child void thr_exit() { cond_signal(&c); Does this work? If not, what s the problem? Child may run and call cond_signal() before parent called cond_wait() Parent will sleep indefinitely

Thread Join: Attempt 2 Parent void thr_join() { if (done == 0) { cond_wait(&c); Let s keep some state then Is there a problem here? Child void thr_exit() { done = 1; cond_signal(&c);

Thread Join: Attempt 2 Parent void thr_join() { if (done == 0) { cond_wait(&c); Let s keep some state then Parent: a b Child: x y Again, parent may sleep indefinitely Solution? //a //b Child void thr_exit() { done = 1; cond_signal(&c); //x //y

Using Locks to Achieve Atomicity Waiting Thread if (! check_cond()) cond_wait(&c, &m); Waking Thread set_cond(); cond_signal(&c); Need a lock (called mutex in pthreads) to ensure two things 1) Checking condition (waiting thread) & modifying it (waking thread) remain mutually exclusive 2) Checking condition & putting thread to sleep (waiting thread) remain atomic cond_wait() should unlock mutex atomically w/ going to sleep If mutex not released, waking thread cannot make progress If release is not atomic, we get a race condition. Can you identify it?

Using Locks to Achieve Atomicity cond_wait() releases the mutex atomically with going to sleep cond_wait() re-acquires the mutex immediately after being awoken (before returning) To be safe, should always be holding mutex when calling cond_signal()

Spurious Wakeups In most systems, a sleeping thread might be awoken spuriously In addition to being awoken when signaled So, no guarantee that condition you ve been waiting for is true when you are awoken Need to check the condition again before continuing How? Waiting Thread while (! check_cond()) cond_wait(&c, &m);

Thread Join: Correct Solution Parent void thr_join() { while (done == 0) cond_wait(&c, &m); Child void thr_exit() { done = 1; cond_signal(&c); This code works for one parent and one child Does it work for one parent and multiple children? Yes What if there were multiple parents each with multiple children? It won t work; we ll revisit that case later

Exercise Implement cond_wait and cond_signal Hine: can use park(), unpark() and setpark() As we did for the queue lock

Recap: CV Rules of Thumb (Take 1) Shared state determines if condition is true or not Check the state before waiting on cv In a while loop Use a mutex to protect 1) the shared state on which condition is based, as well as, 2) operations on the cv Remember to acquire the mutex before calling cond_signal()

Example 2: Bounded Buffer Classic producer/consumer problem Multiple producers and multiple consumers communicate using a shared, finite-size buffer Producers add items to buffer If buffer is full, producer has to wait until there is free space Consumers remove items from buffer If buffer is empty, consumer has to wait until one or more items are added Common examples: Unix pipe: bounded buffer in kernel (multiple producers & consumers) Work queue in a web server (one producer, multiple consumers)

Bounded Buffer: Attempt 1 Producer Consumer for (int i=0; i<loops; i++) { while (numfull == MAX) cond_wait(&cond, &m); do_fill(i); cond_signal(&cond); Starting simple: assume one producer, one consumer numfull: number of elements in the buffer Does this code work for 1P and 1C? Yes while(1) { while (numfull == 0) cond_wait(&cond, &m); int tmp = do_get(); cond_signal(&cond); printf( %d\n, tmp);

Bounded Buffer: Attempt 1 Producer Consumer for (int i=0; i<loops; i++) { while (numfull == MAX) cond_wait(&cond, &m); //a do_fill(i); //b cond_signal(&cond); //c How about 1P and 2C? Would it work? No Why? while(1) { while (numfull == 0) cond_wait(&cond, &m); //x int tmp = do_get(); //y cond_signal(&cond); //z printf( %d\n, tmp);

Bounded Buffer: Attempt 1 Say queue size is one (i.e., it can hold only one item) C1 and C2 initially find queue empty so they are waiting (line x) 1) P adds an item to buffer (line b), signals cond (line c), waking up C1, waits on cond until signaled (line a) 2) C1 is awoken, removes item from buffer (line y), signals cond (line z), waking up C2, finds buffer empty, goes to sleep (line x) 3) C2, being woken up by C1, finds buffer empty, goes to sleep waiting on cond (line x) Everyone is sleeping P can t produce no forward progress Crux: C1 s signal was meant to awaken P but it awoke C2

Solution 1: Wake up Everyone When not sure if next waiting thread is the right one to wake up, just wake up all Not the most elegant solution (that s Solution 2) Probably bad for performance: all awoken threads will compete for mutex again But a good fallback mechanism to ensure correctness Need a new API: cond_broadcast(cv) Semantic: wakes up all the queues waiting on cv There are cases where there is no elegant solution and we have to use broadcast See the memory allocator example in OSTEP, Section 30.3

Solution 2: Use Multiple CVs Identify different conditions that need waiting for Use a separate CV for each condition using cond_wait() and cond_signal() More elegant, better-performing solution than using cond_broadcast() Different conditions in bounded buffer problem? Two Waiting for queue to become non-full Waiting for queue to become non-empty

Bounded Buffer: Correct & Elegant Solution Producer Consumer for (int i=0; i<loops; i++) { while (numfull == MAX) cond_wait(&non_full, &m); do_fill(i); cond_signal(&non_empty); Would it be okay also to use two mutexes? No while(1) { while (numfull == 0) cond_wait(&non_empty, &m); int tmp = do_get(); cond_signal(&non_full); printf( %d\n, tmp); Why? Because mutex protects associated with the shared state (buffer, in this case)

Example 3: Join w/ Multiple Parents Parent 1 Parent 2 pthread_t p1, p2; pthread_t p1, p2; // create child threads pthread_create(&p1, NULL, mythread, "A"); pthread_create(&p2, NULL, mythread, "B"); // create child threads pthread_create(&p1, NULL, mythread, "C"); pthread_create(&p2, NULL, mythread, "D"); // // // join waits for the child threads to finish thr_join(p1, NULL); thr_join(p2, NULL); return 0; // join waits for the child threads to finish thr_join(p1, NULL); thr_join(p2, NULL); return 0; Consider multiple parents each with multiple children However, each child only has one parent Assume a parent thread may only join its own children NOTE: This semantic is different from pthread_join()

Example 3: Join w/ Multiple Parents Parent Child void thr_join(int i) { while (done[i] == 0) cond_wait(&c, &m); void thr_exit() { done[my_id] = 1; cond_signal(&c); Obviously we need an array of done flags, one per child Is this code correct? No When a child signals c, it is not guaranteed to awaken its own parent Solutions: 1) Use cond_broadcast() to awaken all sleeping parents 2) Use cond_signal() but use a separate CV for each parent 3) Use cond_signal() but use a separate CV for each child

Example 3: Solution 1 Parent Child void thr_join(int i) { while (done[i] == 0) cond_wait(&c, &m); void thr_exit() { done[my_id] = 1; cond_broadcast(&c); Obviously we need an array of done flags, one per child Is this code correct? No When a child signals c, it is not guaranteed to awaken its own parent Solutions: 1) Use cond_broadcast() to awaken all sleeping parents 2) Use cond_signal() but use a separate CV for each parent 3) Use cond_signal() but use a separate CV for each child

Example 3: Solution 2 Parent Child void thr_join(int i) { while (done[i] == 0) cond_wait(&c[my_id], &m); void thr_exit() { done[my_id] = 1; cond_signal(&c[my_parent]); Obviously we need an array of done flags, one per child Is this code correct? No When a child signals c, it is not guaranteed to awaken its own parent Solutions: 1) Use cond_broadcast() to awaken all sleeping parents 2) Use cond_signal() but use a separate CV for each parent 3) Use cond_signal() but use a separate CV for each child

Example 3: Solution 3 Parent Child void thr_join(int i) { while (done[i] == 0) cond_wait(&c[i], &m); void thr_exit() { done[my_id] = 1; cond_signal(&c[my_id]); Obviously we need an array of done flags, one per child Is this code correct? No When a child signals c, it is not guaranteed to awaken its own parent Solutions: 1) Use cond_broadcast() to awaken all sleeping parents 2) Use cond_signal() but use a separate CV for each parent 3) Use cond_signal() but use a separate CV for each child

Recap: CV Rules of Thumb (Take 2) Shared state determines if condition is true or not Check the state before waiting on cv In a while loop Use a mutex to protect 1) the shared state on which condition is based, as well as, 2) operations on the cv Remember to acquire the mutex before calling cond_signal() and cond_broadcast() Use different CVs for different conditions Sometimes, cond_broadcast() helps if you can t find an elegant solution using cond_signal()

Pthreads Condition Variable API Creation/destruction pthread_cond_init(cv, attr) pthread_cond_destroy(cv) pthread_condattr_init(attr) pthread_condattr_destroy(attr) Waiting and waking pthread_cond_wait(cv, mutex) pthread_cond_timedwait(cv, mutex, time) pthread_cond_signal(cv) pthread_cond_broadcast(cv) Required reading linked on the course schedule page

Semaphores A synchronization primitive that can work both as a lock, as well as a special case of condition variables In particular, for Bounded Buffer problem Not easy to use as a general condition variable Not easy to use to build a general condition variable Doable but quite difficult See Microsoft Research s attempt at http://research.microsoft.com/pubs/64242/implementi ngcvs.pdf

Semaphores (2) Read more in OSTEP, Chapter 31 More of an intellectual curiosity, IMHO A nice one though, worth reading about Pthreads just have locks and condition variables, but no semaphores