1 / 38

Review

Review. The Critical Section problem Peterson’s Algorithm Implementing Atomicity Busy waiting Blocking. Outline. Semaphores what they are how they are used Monitors what they are how they are used. What’s wrong with this picture?. Our solutions to CS have two unappealing features:

Download Presentation

Review

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. Review • The Critical Section problem • Peterson’s Algorithm • Implementing Atomicity • Busy waiting • Blocking

  2. Outline • Semaphores • what they are • how they are used • Monitors • what they are • how they are used

  3. What’s wrong with this picture? Our solutions to CS have two unappealing features: • They are mistifying and unclear • They use busy waiting

  4. Semaphores A semaphore consists of: • A variable s • A thread set T • A function P (Passeren;wait) • A function V (Vrijgeven; signal) syntax example: Semaphore s(5);

  5. Semaphore Operations Initialization(val) { s = val ; T = ^; }

  6. P(s) s--; if(s < 0) { add caller thread to T; block; } This code executes atomically.

  7. V(s) s++; if(s 0) { Remove a thread t from T; Unblock(t); } This code executes atomically.

  8. Thread T0 while (!terminate) { <entry0> CS <exit0> NCS0 } Thread T1 while (!terminate) { <entry1> CS <exit1> NCS1 } P(s); P(s); V(s); V(s); Mutual exclusion with semaphores init: s = 1

  9. Questions, Questions... • What if we have n threads instead of 2? • What if we want to allow at most k threads in the CS?

  10. Binary Semaphore Two types: • Counting semaphores • s takes any values • Binary semaphores • s takes only 0 or 1

  11. P(s) if (s == 0) { Add caller thread to T; Block; } else s--; Binary Semaphores V(s) if (T != ) { Remove a thread t from T; Unblock(t); } else if (s == 0) s = 1;

  12. Important properties of Semaphores -I • Semaphores are non-negative integers • The only operations you can use to change the value of a semaphore are P() and V() (except for the initial setup) • Semaphores have two uses • Mutual exclusion: you know all about it • Synchronization: how do we make sure that T1 completes execution before T2 starts?

  13. Important Propertiesof Semaphores- II • We assume that a semaphore is fair: No thread t that is blocked because of a P(s) operation remains blocked if s is V’d infinitely often Does this guarantee bounded waiting? • In practice, FIFO is mostly used, transforming the set into a queue. • V(s) never blocks. • Binary semaphores are as expressive as general semaphores (given one can implement the other) • But they are different: {s = 0} V(s) V(s) P(s) P(s) VS {s = 0} Vb(s) Vb(s) Pb(s) Pb(s)

  14. Classic Problems: Producer-Consumer I • Producer adds items to a shared buffer • Consumer takes them out • Buffer avoids producers and consumers to proceed in lock step • Buffer is finite Examples: • cpp|cc|as • coke machine • ready queue in a multithreaded multiprocessor • ….

  15. Producer Consumer II • Two types of constraint: • Mutual Exclusion • Only one thread can manipulate the buffer at any one time • Condition Synchronization • Consumer must wait if buffer is empty • Producer must wait if buffer is full • Are these safety or liveness properties?

  16. Producer Consumer III • Use a separate semaphore for each constraint Semaphore mutex; // protects the shared buffer Semaphore fullSlots; // counts full slots: if 0, no // coke Semaphore emptySlots; // counts empty slots: if 0, // nowhere to put more coke

  17. Semaphore new mutex (1); Semaphore new emptySlots(numSlots); Semaphore new fullSlots(0); Producer() { P(emptySlots); P(mutex); put 1 coke in the machine V(mutex); V(fullSlots); } Consumer() { P(fullSlots); P(mutex); take a coke out V(mutex); V(emptySlots); } Producer Consumer IV Is the order of Ps important? Is the order of Vs important?

  18. Beyond Semaphores • Semaphores huge step forward (immagine having to do producer consumer with Peterson’s algorithm…) • BUT…Semaphores are used both for mutex and condition synchronization • hard to read code • hard to get code right

  19. Monitors (late 60’s, early 70’s) • A programming language construct, much like what we call today objects • Consists of: • General purpose variables • Methods • Initialization code (constructor) • Condition variables • Can implement a monitor-like style of programming without without the language construct, using a combination of locks and condition variables

  20. Locks A lock provides mutual exclusion to shared data: Lock::Acquire() – wait until lock is free, then grab it Lock::Release() – unlock; wake up anyone waiting in Acquire Rules: • Always acquire before accessing a shared data structure • Always release after finishing with shared data structure • Lock is initially free

  21. Example: Producer Consumer addToBuff() { lock.Acquire(); // lock before using shared data put item on buffer, if there is space lock.Release(); } removeFromBuff() { lock.Acquire(); // lock before using shared data if something on buffer, remove it lock.Release(); return item; }

  22. Houston, we have a problem… • How do we change removeFromBuff so that it check if there is something in the buffer before trying to remove it? • Logically, want to suspend thread inside the critical section • What is the problem? • Solution: suspend and atomically release lock

  23. Condition Variables A queue of threads waiting for something inside the critical section (why does it not violate safety?) Condition variables have two operations: • Wait() • Calling thread blocks, releases lock (gives up monitor) • Wait on a queue until someone signals variable • Signal() • Unblock someone who was waiting on the variable • Broadcast() • Unblock all waiting on the variable

  24. Producer Consumer, again addToBuff() { lock.Acquire(); // lock before using shared data put item on buffer condition.signal(); lock.Release(); } removeFromBuff() { lock.Acquire(); // lock before using shared data while nothing on buffer { condition.wait(&lock) } remove item from buffer lock.Release(); return item; }

  25. A dilemma • What happens to a thread that signals on a condition variable while in the middle of a critical section?

  26. Hoare Monitors • Assume thread Q waiting on condition x • Assume thread P is in the monitor • Assume thread P calls x.signal • P gives up monitor, P blocks! • Q takes over monitor, runs • Q finishes, gives up monitor • P takes over monitor, resumes

  27. fn1(…) … x.wait // T1 blocks // T1 resumes // T1 finishes fn4(…) … x.signal // T2 blocks // T2 resumes Example: Hoare Monitors

  28. Per Brinch Hansen’s Monitors • Assume thread Q waiting on condition x • Assume thread P is in the monitor • Assume thread P calls x.signal • P continues, finishes • Q takes over monitor, runs • Q finishes, gives up monitor

  29. fn1(…) … x.wait // T1 blocks // T1 resumes // T1 finishes fn4(…) … x.signal // T2 continues // T2 finishes Example: Hansen Monitors

  30. Hoare Awkward in programming Cleaner, good for mathematical proofs Main advantage: when a condition variable is signalled, condition does not change Used bymost textbooks Hansen Easier to program Can lead to synchronization bugs Used by most systems Tradeoff

  31. Classic Problems 2:Readers-Writers • Motivation: shared database (bank, seat reservation system) • Two classes of users: • readers (never modify database) • writers (read and modify database) • Want to maximize concurrency • at most one writer in database • if no writer, any number of readers in database

  32. Towards a solution State variables: • ar --- active readers (readers in CS) • aw --- active writers (writers in CS) Condition variables: • oktoread (readers can enter critical section) • oktowrite (writer can enter critical section) Safety ar ≥ 0  aw ≥ 0  (aw = 0  (aw = 1  ar = 0))

  33. Database::read() wait until no writers access database if no readers in database, let writer in Database::write() wait until no readers or writers access database wake up waiting readers and writers Structure of the solution Use procedures startRead, doneRead, startWrite, doneWrite

  34. Database::startRead() { lock.Acquire(); while (aw) { okToRead.Wait(&lock); } ar:= ar+1; okToRead.signal; lock.Release(); } Database::doneRead() { lock.Acquire(); ar :=ar –1; if (ar =0) {okToWrite.signal} lock.Release(); } Database::startWrite() { lock.Acquire(); while (aw  ar) { okToWrite.Wait(&lock) } aw := 1; lock.Release(); } Database::doneWrite() { lock.Acquire(); aw := 0; okToRead.signal; okToWrite.signal; lock.Release(); } The procedures

  35. Semaphores and Monitors - I Can we build monitors using semaphores? Try 1: Wait() {P(s)} Signal() {V(s)} Try 2: Wait(Lock *lock) { Signal() { lock.Release(); V(s); P(s); } lock.Acquire(); }

  36. Semaphores and Monitors-II Try 3: Signal() { if semaphore queue is not empty {V(s)} } REMEMBER: • If a thread signals on a condition on which no thread is waiting, the result is a no-op. • If a thread executes a V on a semaphore on which no thread is waiting, the semaphore is incremented!

  37. A few matters of style • Always do things the same way • Always use monitors (condition variables plus locks) • Always hold lock when operating on a condition variable • Always grab lock at the beginning of a procedure and release it before return • Always use while (not if) to check for the value of a condition variable • (Almost) never use sleep to synchronize

  38. Example: Java • Each object has a monitor • User can specify the keyword “synchronized” in front of methods that must execute with mutual exclusion • Use Hansen monitors • No individually named condition variables (just one anonymous condition variable) • wait() • notify() • notifyAll()

More Related