1 / 115

CS 333 Introduction to Operating Systems Class 6 – Monitors and Message Passing

Jonathan Walpole Computer Science Portland State University. CS 333 Introduction to Operating Systems Class 6 – Monitors and Message Passing. Monitors. It is difficult to produce correct programs using semaphores correct ordering of up and down operations is tricky!

afya
Télécharger la présentation

CS 333 Introduction to Operating Systems Class 6 – Monitors and Message Passing

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Jonathan Walpole Computer Science Portland State University CS 333Introduction to Operating Systems Class 6 – Monitors and Message Passing

  2. Monitors • It is difficult to produce correct programs using semaphores • correct ordering of up and down operations is tricky! • Can we get the compiler to generate the correct semaphore code for us? • what are suitable higher level abstractions for synchronization?

  3. Monitors • Collect related shared objects together in a monitor • Characteristics • Local data variables are accessible only via the monitor’s procedures • Processes enter the monitor by invoking one of its procedures • Only one process may execute within the monitor at a given time • Condition variables (cv) • Wait(cv) – block on condition • Signal(cv) – wake up process waiting on cv

  4. shared data monitor entry queue condition queues x y monitor operations initialization code Monitor structures

  5. Monitor example for mutual exclusion process Producer begin loop <produce char “c”> BoundedBuffer.deposit(c) end loop end Producer monitor: BoundedBuffer var buffer : ...; nextIn, nextOut :... ; entry deposit(c: char) begin ... end entry remove(var c: char) begin ... end end BoundedBuffer process Consumer begin loop BoundedBuffer.remove(c) <consume char “c”> end loop end Consumer

  6. Condition variables • Condition variables allow processes to synchronize based on some state of the monitor variables • For example: Buffer_full in the producer/consumer • Operations wait(cv) and signal(cv) allow synchronization within a monitor • Only one processor active at one time • what happens on a signal from A to B? • A waits for B to leave monitor, or waits for another condition • B waits for A to leave monitor, or waits for another condition • … and what happens on wait?

  7. Monitor example monitor : BoundedBuffer var buffer : array[0..n-1] of char nextIn,nextOut : 0..n-1 := 0 fullCount : 0..n := 0 notEmpty, notFull : condition entry deposit(c:char) entry remove(var c: char) begin begin if (fullCount = n) then if (fullCount = n) then wait(notFull) wait(notEmpty) end if end if buffer[nextIn] := c c := buffer[nextOut] nextIn := nextIn+1 mod n nextOut := nextOut+1 mod n fullCount := fullCount+1 fullCount := fullCount-1 signal(notEmpty) signal(notFull) end deposit end remove end BoundedBuffer

  8. Condition synchronization semantics • Signaling and signaled processes can not both run • What if signaling process continues to run and signals other condition variable? • What if signaled process continues to run and signals other condition variables? • What order should processes run? • How do you avoid deadlock?

  9. Condition synchronization semantics • Hoare Semantics • On signal, allow signalled process to run; upon its exit from the monitor, signaller process continues • Stonger guarantees • Easier to prove correctness • Mesa Semantics (Xerox PARC) • Signal is merely a “hint” • Requires process to check that condition is ok to continue upon receipt of signal

  10. Producer consumer with message passing

  11. Barriers • Use of a barrier • processes approaching a barrier • all processes but one blocked at barrier • last process arrives, all are let through

  12. Summary • Process synchronization topics • Semaphores • IPC problems • Monitors • Reading • 2.3-2.4

  13. Monitors • It is difficult to produce correct programs using semaphores • correct ordering of up and down is tricky! • avoiding deadlock is tricky! • boundary conditions are tricky! • Can we get the compiler to generate the correct semaphore code for us? • what are suitable higher level abstractions for synchronization?

  14. Monitors • Collect related shared objects together in a monitor • Encapsulation and mutual exclusion • Local data variables are accessible only via the monitor’s procedures • Processes enter the monitor by invoking one of its procedures • Only one process may execute within the monitor at a given time • Condition variables (cv) • Wait(cv) – process blocked (queued) until condition holds • Signal(cv) – signals the condition and unblocks (dequeues) a process

  15. shared data monitor entry queue condition queues x y monitor operations initialization code Monitor structures

  16. Monitor example for mutual exclusion process Producer begin loop <produce char “c”> BoundedBuffer.deposit(c) end loop end Producer monitor: BoundedBuffer var buffer : ...; nextIn, nextOut :... ; entry deposit(c: char) begin ... end entry remove(var c: char) begin ... end end BoundedBuffer process Consumer begin loop BoundedBuffer.remove(c) <consume char “c”> end loop end Consumer

  17. Monitor example with condition variables monitor : BoundedBuffer var buffer : array[0..n-1] of char nextIn,nextOut : 0..n-1 := 0 fullCount : 0..n := 0 notEmpty, notFull : condition entry deposit(c:char) entry remove(var c: char) begin begin if (fullCount = n) then if (fullCount = n) then wait(notFull) wait(notEmpty) end if end if buffer[nextIn] := c c := buffer[nextOut] nextIn := nextIn+1 mod n nextOut := nextOut+1 mod n fullCount := fullCount+1 fullCount := fullCount-1 signal(notEmpty) signal(notFull) end deposit end remove end BoundedBuffer

  18. Monitor design choices • Condition variables introduce a problem for mutual exclusion • only one process active in the monitor at a time, so what to do when a process is unblocked on signal? • must not block holding the mutex, so what to do when a process blocks on wait? • Should signals be stored/remembered? • signals are not stored • if signal occurs before wait, signal is lost! • Should condition variables count?

  19. Monitor design choices • Choices when A signals a condition that unblocks B • A waits for B to exit the monitor or blocks again • B waits for A to exit the monitor or block • Signal causes A to immediately exit the monitor or block (on what condition?) • Choices when A signals a condition that unblocks B & C • B is unblocked, but C remains blocked • C is unblocked, but B remains blocked • Choices when A calls wait and blocks • a new external process is allowed to enter • but which one?

  20. Common monitor semantics • Hoare semantics • On signal, allow signaled process to run; upon its exit from the monitor, signaler process continues • Brinch Hansen semantics • signaler must immediately exit following signal

  21. Message Passing • Interprocess communication • via shared memory • across machine boundaries • Message passing can be used locally or remotely for synchronization or general communication • processes use send and receive primitives • receive can block like wait • send unblocks a process blocked on receive (like signal unblocking a waiting process)

  22. Producer consumer with message passing

  23. Design Choices for Message Passing • Mailboxes • system maintains a buffer of sent, but not yet received, messages • Rendezvous • sender and receiver must be active at the same time • receive must be blocked before send occurs • kernel does no buffering • when does the send return?

  24. Barriers • Use of a barrier • processes approaching a barrier • all processes but one blocked at barrier • last process arrives, all are let through

  25. Monitors (1) Example of a monitor

  26. Monitors (2) • Outline of producer-consumer problem with monitors • only one monitor procedure active at one time • buffer has N slots

  27. Monitors (3) Solution to producer-consumer problem in Java (part 1)

  28. Monitors (4) Solution to producer-consumer problem in Java (part 2)

  29. Semantics of monitors • What is the strongest statement we can make about the state of the monitor after a waiter wakes up? entry deposit(c:char) entry remove(var c: char) begin begin if (fullCount = n) then : : wait(notFull) c := buffer[nextOut] fullCount := fullCount-1 end if signal(notFull) : : end deposit end remove

  30. Synchronization problems with Mesa P1 P2 P3 /* fullCount=n */ if (fullCount==n) wait(notFull); remove() ... fullCount--; signal(notFull); ... /* exit monitor */ /* fullCount=n-1*/ deposit() ... fullCount++; ... /* exit monitor */ ... fullCount++;

  31. Mesa semantics monitor : BoundedBuffer var buffer : array[0..n-1] of char nextIn,nextOut : 0..n-1 := 0 fullCount : 0..n := 0 notEmpty, notFull : condition entry deposit(c:char) entry remove(var c: char) begin begin while (fullCount = n) then while (fullCount = n) then wait(notFull) wait(notEmpty) end while end while buffer[nextIn] := c c := buffer[nextOut] nextIn := nextIn+1 mod n nextOut := nextOut+1 mod n fullCount := fullCount+1 fullCount := fullCount-1 signal(notEmpty) signal(notFull) end deposit end remove end BoundedBuffer

  32. Introduction to Operating Systems Chapter 2 (partial)Monitors, Reentrant Code, Message Passing, and Barriers

  33. Introduction • It is difficult to produce correct programs • using locks and semaphores!!! • Correct ordering of Up and Down operations is tricky! • Desirable: • Language / compiler support for IPC • What are suitable high-level abstractions for synchronization?

  34. Monitors • Collect related, shared objects together in a “monitor” • Characteristics: • • Local data variables are accessible only via the monitor’s procedures/methods • • Threads enter the monitor by invoking one of its procedures/methods • • Only one thread may execute within the monitor at a given time • “Condition Variables” (cv) • Wait(cv) – block on condition • Signal(cv) – wake up one thread waiting on cv

  35. Monitor structures shared data monitor entry queue x condition variables y “entry” methods local methods initialization code

  36. Monitor structures shared data monitor entry queue x condition variables y Local to monitor (Each has an associated list of waiting threads) List of threads waiting to enter the monitor “entry” methods Can be called from outside the monitor. Only one active at any moment. local methods initialization code

  37. Example: The “Bounded-Buffer” Monitor monitor BoundedBuffer var buffer: ... nextIn, nextOut :... entry deposit(c: char) begin ... end entry remove() begin ... return c end endMonitor Producer Thread: while true -- Produce char “c” BoundedBuffer.deposit(c) endWhile Consumer Thread: while true c = BoundedBuffer.remove() -- Consume char “c” endWhile

  38. The “BoundedBuffer” Monitor monitor BoundedBuffer var buffer: array[n] ofchar nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) ... entry remove() ... endMonitor nextOut nextIn A B D C 0 N-1 cntFull=4

  39. Code for the “deposit” entry routine monitor BoundedBuffer var buffer: array[n] ofchar nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) if cntFull == N notFull.Wait() endIf buffer[nextIn] = c nextIn = (nextIn+1) mod N cntFull = cntFull + 1 notEmpty.Signal() endEntry entry remove() ... endMonitor nextOut nextIn A B D C 0 N-1 cntFull=4

  40. Code for the “remove” entry routine monitor BoundedBuffer var buffer: array[n] ofchar nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) ... entry remove() if cntFull == 0 notEmpty.Wait() endIf c = buffer[nextOut] nextOut = (nextOut+1) mod N cntFull = cntFull - 1 notFull.Signal() endEntry endMonitor nextOut nextIn A B D C 0 N-1 cntFull=4

  41. Condition Variables • “Condition variables allow processes to synchronize based on some state of the monitor variables.” • Examples from producer/consumer: • “Buffer-Full” condition • “Buffer-Empty” condition • Operations Wait(cv) and Signal(cv) • allow synchronization within the monitor • When a producer thread adds an element... • A consumer may be sleeping • Need to wake the consumer... Signal

  42. Condition synchronization semantics • “Only one thread can be executing in the monitor • at any one time.” • Scenario: • Thread A is executing in the monitor. • Thread A does a Signal, waking up thread B. • What happens now? • Signaling and signaled threads can not both run!

  43. Condition synchronization semantics • Option 1: Hoare Semantics • What happens when a Signal is performed? • The signaling thread (A) is suspended. • The signaled thread (B) wakes up and runs immediately. • B can assume the condition is now true/satisfied • • Stronger guarantees • • Easier to prove correctness • When B leaves monitor, then A can run. • After B leaves monitor... • A might resume execution immediately • ... or maybe another thread (C) will slip in!

  44. Condition synchronization semantics • Option 2: MESA Semantics (Xerox PARC) • What happens when a Signal is performed? • • The signaling thread (A) continues. • • The signaled thread (B) waits. • When A leaves monitor, then B runs. • Issue: What happens when B waits? • When A leaves the monitor, • can some other thread (C) slip in first? • (Can some other thread (C) run • after A signals, but before B runs?) • • A signal is more like a hint. • • Requires B to recheck the state of the monitor variables • to see if it can proceed or must wait some more.

  45. Code for the “deposit” entry routine monitor BoundedBuffer var buffer: array[n] ofchar nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) if cntFull == N notFull.Wait() endIf buffer[nextIn] = c nextIn = (nextIn+1) mod N cntFull = cntFull + 1 notEmpty.Signal() endEntry entry remove() ... endMonitor Hoare Semantics

  46. Code for the “deposit” entry routine monitor BoundedBuffer var buffer: array[n] ofchar nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) while cntFull == N notFull.Wait() endWhile buffer[nextIn] = c nextIn = (nextIn+1) mod N cntFull = cntFull + 1 notEmpty.Signal() endEntry entry remove() ... endMonitor MESA Semantics

  47. Code for the “remove” entry routine monitor BoundedBuffer var buffer: array[n] ofchar nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) ... entry remove() if cntFull == 0 notEmpty.Wait() endIf c = buffer[nextOut] nextOut = (nextOut+1) mod N cntFull = cntFull - 1 notFull.Signal() endEntry endMonitor Hoare Semantics

  48. Code for the “remove” entry routine monitor BoundedBuffer var buffer: array[n] ofchar nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) ... entry remove() while cntFull == 0 notEmpty.Wait() endWhile c = buffer[nextOut] nextOut = (nextOut+1) mod N cntFull = cntFull - 1 notFull.Signal() endEntry endMonitor MESA Semantics

  49. “Hoare Semantics” • What happens when a Signal is performed? • The signaling thread (A) is suspended. • The signaled thread (B) wakes up and runs immediately. • B can assume the condition is now true/satisfied • From the original Hoare Paper: • “No other thread can intervene [and enter the monitor] between the signal and the continuation of exactly one waiting thread.” • “If more than one thread is waiting on a condition, we postulate that the signal operation will reactivate the longest waiting thread. This gives a simple neutral queuing discipline which ensures that every waiting thread will eventually get its turn.”

  50. Implementing Hoare Semantics • Implementation? • Thread A holds the monitor lock. • Thread A issues a Signal. • Thread B will be moved back to the ready queue. • Thread A must be suspended... • Possession of the monitor lock must be passed • from A to B. • When B finishes and gets ready to return... • The lock can be released. • Thread A must re-aquire the lock. • Perhaps A is blocked, waiting to re-aquire the lock.

More Related