condition synchronization
play

Condition Synchronization People are still trying to figure that - PDF document

Synchronization Now that you have seen locks, is that all there is? No, but what is the right way to build a parallel program. Condition Synchronization People are still trying to figure that out. Compromises: between making it


  1. Synchronization Now that you have seen locks, is that all there is? No, but what is the “ right ” way to build a parallel program. Condition Synchronization Ø People are still trying to figure that out. Compromises: Ø between making it easy to modify shared variables AND Ø restricting when you can modify shared variables. Ø between really flexible primitives AND Ø simple primitives that are easy to reason about. 1 2 Beyond Locks Beyond Locks Locks ensure mutual exclusion Synchronizing on a condition. Bounded Buffer problem – producer puts things in a Ø When you start working on a synchronization problem, first define the mutual exclusion constraints, then ask “ when does fixed sized buffer, consumer takes them out. a thread wait ” , and create a separate synchronization Ø Synchronizing on a condition. variable representing each constraint. Class BoundedBuffer{ Bounded Buffer problem – producer puts things in a … void* buffer[]; fixed sized buffer, consumer takes them out. What is wrong Lock lock; with this? Ø What are the constraints for bounded buffer? int count = 0; Ø 1) only one thread can manipulate buffer queue at a time } ( mutual exclusion) BoundedBuffer::Remove(c){ BoundedBuffer::Deposit(c){ lock à acquire(); lock à acquire(); Ø 2) consumer must wait for producer to fill buffers if none full while (count == 0); // spin while (count == n); //spin ( scheduling constraint) Remove c from buffer; Add c to the buffer; Ø 3) producer must wait for consumer to empty buffers if all full count--; count++; ( scheduling constraint) lock à release(); lock à release(); } } 3 4 Beyond Locks Beyond Locks Class BoundedBuffer{ Class BoundedBuffer{ … … void* buffer[]; void* buffer[]; What is wrong What is wrong Lock lock; Lock lock; int count = 0; with this? int count = 0; with this? } } BoundedBuffer::Remove(c){ BoundedBuffer::Remove(c){ BoundedBuffer::Deposit(c){ BoundedBuffer::Deposit(c){ while (count == 0); // spin if (count == 0) sleep(); while (count == n); //spin if (count == n) sleep(); lock à acquire(); lock->acquire(); lock à acquire(); lock->acquire(); Remove c from buffer; Remove c from buffer; Add c to the buffer; Add c to the buffer; count--; count--; count++; count++; lock à release(); lock->release(); lock à release(); lock->release(); } if(count==n-1) wakeup(deposit); } if(count == 1) wakeup(remove); } } 5 6

  2. Beyond Locks Beyond Locks Class BoundedBuffer{ … What is wrong void* buffer[]; with this? Lock lock; Class BoundedBuffer{ int count = 0; } … void* buffer[]; What is wrong Lock lock; BoundedBuffer::Remove(c){ with this? int count = 0; BoundedBuffer::Deposit(c){ while(1) { } while(1) { lock à acquire(); lock à acquire(); if (count == 0) { BoundedBuffer::Remove(c){ BoundedBuffer::Deposit(c){ if(count == n) { lock->release(); lock à acquire(); lock à acquire(); lock->release(); continue; if (count == 0) sleep(); continue;} if (count == n) sleep(); } Remove c from buffer; Add c to the buffer; Add c to the buffer; Remove c from buffer; count--; count++; count++; count--; if(count==n-1) wakeup(deposit); if(count == 1) wakeup(remove); lock à release(); lock à release(); lock à release(); lock à release(); break; break; } } }} }} 7 8 Introducing Condition Variables Condition Variables: Operations Correctness requirements for bounded buffer producer- Three operations Wait() usually specified a lock consumer problem Ø Wait() to be released as a parameter Ø Only one thread manipulates the buffer at any time (mutual ❖ Release lock exclusion) ❖ Go to sleep Ø Consumer must wait for producer when the buffer is empty ❖ Reacquire lock upon return (scheduling/synchronization constraint) ❖ Java Condition interface await() and awaitUninterruptably() Ø Producer must wait for the consumer when the buffer is full Ø Notify() (historically called Signal()) (scheduling/synchronization constraint) ❖ Wake up a waiter, if any ❖ Condition interface signal() Ø NotifyAll() (historically called Broadcast()) Solution: condition variables ❖ Wake up all the waiters Ø An abstraction that supports conditional synchronization ❖ Condition interface signalAll() Ø Condition variables are associated with a monitor lock Ø Enable threads to wait inside a critical section by releasing the Implementation monitor lock. Ø Requires a per-condition variable queue to be maintained Ø Threads waiting for the condition wait for a notify() 9 10 Implementing Wait() and Notify() Using Condition Variables: An Example Condition::Notify(lock){ schedLock->acquire(); if (lock->numWaiting > 0) { Coke machine as a shared buffer Move a TCB from waiting queue to ready queue; lock->numWaiting--; Two types of users } Ø Producer: Restocks the coke machine schedLock->release(); Ø Consumer: Removes coke from the machine } Requirements Condition::Wait(lock){ Why do we need Ø Only a single person can access the machine at any time schedLock->acquire(); schedLock? Ø If the machine is out of coke, wait until coke is restocked lock->numWaiting++; Ø If machine is full, wait for consumers to drink coke prior to restocking lock à release(); Put TCB on the waiting queue for the CV; How will we implement this? schedLock->release() switch(); Ø What is the class definition? lock à acquire(); Ø How many lock and condition variables do we need? } 11 12

  3. Coke Machine Example Word to the wise… Class CokeMachine{ Always wait and notify condition variables with the … mutex held. Storge for cokes (buffer) Lock lock; Period. int count = 0; Condition notFull, notEmpty; } Ø Fine print: There are cases where notification outside of a lock can be safe, but the code tends to be fragile, error- CokeMachine::Deposit(){ CokeMachine::Remove(){ prone, and easy for another developer to break. lock à acquire(); lock à acquire(); Ø In many cases you can lose notifications and hang (liveness) while (count == n) { while (count == 0) { notFull.wait(&lock); } notEmpty.wait(&lock); } Ø Moreover there is no clear advantage to breaking this Add coke to the machine; Remove coke from to the machine; convention. So just don’t do it. count++; count--; notEmpty.notify(); notFull.notify(); lock à release(); lock à release(); } } 13 14 Summary Java syntax for condition variables Non-deterministic order of thread execution è concurrency Condition variables created from locks problems import java.util.concurrent.locks.ReentrantLock; Ø Multiprocessing public static final aLock = new ReentrantLock(); ❖ A system may contain multiple processors è cooperating threads/ processes can execute simultaneously public static ok = aLock.newCondition(); Ø Multi-programming public static int count; ❖ Thread/process execution can be interleaved because of time-slicing aLock.lock(); try { Goal: Ensure that your concurrent program works under ALL possible interleaving while(count < 16){ok.awaitUninterruptably()} } finally { Define synchronization constructs and programming style for aLock.unlock(); developing concurrent programs } ❖ Locks à provide mutual exclusion return 0; ❖ Condition variables à provide conditional synchronization 15 16

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend