Slide 1Synchronization ConstructsIntroducing MonitorsCritical Section: MonitorsRemember Condition VariablesCoke Machine – Example MonitorSlide 7Hoare Monitors: SemanticsHansen (Mesa) Monitors: SemanticsTradeoffProblems with Monitors Nested Monitor CallsMore Monitor Headaches The priority inversion problemOther Interesting TopicsSemaphoresImportant properties of SemaphoresSlide 16Using Semaphores for Mutual ExclusionCoke Machine ExampleRevisiting Coke Machine ExampleImplementing SemaphoresSlide 21The Problem with SemaphoresComparing Semaphores and MonitorsSummary1Semaphores and Monitors: High-level Synchronization Constructs2Synchronization ConstructsSynchronizationCoordinating execution of multiple threads that share data structuresPast few lectures: Locks: provide mutual exclusionCondition variables: provide conditional synchronizationToday: Historical perspectiveMonitorsAlternate high-level language constructsSemaphoresIntroduced by Dijkstra in 1960sMain synchronization primitives in early operating systems3Separate the concerns of mutual exclusion and conditional synchronizationWhat is a monitor?One lock, andZero or more condition variables for managing concurrent access to shared dataGeneral approach:Collect related shared data into an object/moduleDefine methods for accessing the shared dataMonitors first introduced as programming language constructCalling a method defined in the monitor automatically acquires the lockExamples: Mesa, Java (synchronized methods)Monitors also define a programming conventionCan be used in any language (C, C++, … )Introducing Monitors4Critical Section: MonitorsBasic idea:Restrict programming model Permit access to shared variables only within a critical sectionGeneral program structureEntry section“Lock” before entering critical sectionWait if already lockedKey point: synchronization may involve waitCritical section codeExit section“Unlock” when leaving the critical sectionObject-oriented programming styleAssociate a lock with each shared objectMethods that access shared object are critical sectionsAcquire/release locks when entering/exiting a method that defines a critical section5Remember Condition VariablesLocksProvide mutual exclusionSupport two methodsLock::Acquire() – wait until lock is free, then grab itLock::Release() – release the lock, waking up a waiter, if anyCondition variablesSupport conditional synchronizationThree operationsWait(): Release lock; wait for the condition to become true; reacquire lock upon return (Java wait())Signal(): Wake up a waiter, if any (Java notify())Broadcast(): Wake up all the waiters (Java notifyAll())Two semantics for implementation of wait() and signal()Hoare monitor semanticsHansen (Mesa) monitor semantics6Coke Machine – Example MonitorClass CokeMachine{ … Lock lock; int count = 0; Condition notFull, notEmpty;}Class CokeMachine{ … Lock lock; int count = 0; Condition notFull, notEmpty;}CokeMachine::Deposit(){ lockacquire(); while (count == n) {notFull.wait(&lock); } Add coke to the machine; count++; notEmpty.signal(); lockrelease();}CokeMachine::Deposit(){ lockacquire(); while (count == n) {notFull.wait(&lock); } Add coke to the machine; count++; notEmpty.signal(); lockrelease();}CokeMachine::Remove(){ lockacquire(); while (count == 0) {notEmpty.wait(&lock); } Remove coke from to the machine; count--; notFull.signal(); lockrelease();}CokeMachine::Remove(){ lockacquire(); while (count == 0) {notEmpty.wait(&lock); } Remove coke from to the machine; count--; notFull.signal(); lockrelease();}Does the order of aquire/while(){wait} matter?Order of release/signalmatter?7Every monitor function should start with what?A. waitB. signalC. lock acquireD. lock releaseE. signalAll8Hoare Monitors: SemanticsHoare monitor semantics:Assume thread T1 is waiting on condition xAssume thread T2 is in the monitorAssume thread T2 calls x.signalT2 gives up monitor, T2 blocks!T1 takes over monitor, runsT1 gives up monitorT2 takes over monitor, resumesExamplefn1(…)…x.wait // T1 blocks// T1 resumesLockrelease();fn4(…)…x.signal // T2 blocksT2 resumes9Hansen (Mesa) Monitors: SemanticsHansen monitor semantics:Assume thread T1 waiting on condition xAssume thread T2 is in the monitorAssume thread T2 calls x.signal; wake up T1 T2 continues, finishesWhen T1 get a chance to run,T1 takes over monitor, runsT1 finishes, gives up monitorExample:fn1(…)…x.wait // T1 blocks// T1 resumes// T1 finishesfn4(…)…x.signal // T2 continues// T2 finishes10TradeofHoareClaims:Cleaner, good for proofsWhen a condition variable is signaled, it does not changeUsed in most textbooks…butInefficient implementationNot modular – correctness depends on correct use and implementation of signalHansenSignal is only a hint that the condition may be trueNeed to check condition again before proceedingCan lead to synchronization bugsUsed by most systems (e.g., Java)Benefits:Efficient implementationCondition guaranteed to be true once you are out of while !CokeMachine::Deposit(){ lockacquire(); if (count == n) {notFull.wait(&lock); } Add coke to the machine; count++; notEmpty.signal(); lockrelease();}CokeMachine::Deposit(){ lockacquire(); if (count == n) {notFull.wait(&lock); } Add coke to the machine; count++; notEmpty.signal(); lockrelease();}CokeMachine::Deposit(){ lockacquire(); while (count == n) {notFull.wait(&lock); } Add coke to the machine; count++; notEmpty.signal(); lockrelease();}CokeMachine::Deposit(){ lockacquire(); while (count == n) {notFull.wait(&lock); } Add coke to the machine; count++; notEmpty.signal(); lockrelease();}11Problems with MonitorsNested Monitor CallsWhat happens when one monitor calls into another?What happens to CokeMachine::lock if thread sleeps in CokeTruck::Unload?What happens if truck unloader wants a coke?CokeMachine::Deposit(){ lockacquire(); while (count == n) {notFull.wait(&lock); } truck->unload(); Add coke to the machine; count++; notEmpty.signal(); lockrelease();}CokeMachine::Deposit(){ lockacquire(); while (count == n) {notFull.wait(&lock); }
View Full Document