1 / 13

Synchronize or Sink! - A Tutorial on Semaphore Usage

This tutorial discusses the problem of synchronization in a producer-consumer scenario and presents the solution using semaphores. It also covers the use of semaphores in handling multiple consumers.

rnicholson
Download Presentation

Synchronize or Sink! - A Tutorial on Semaphore Usage

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. Tutorial 3 Sync or sink! presented by: Antonio Maiorano Paul Di Marco

  2. What’s the problem? • Example • A cup of coffee • A “pourer” (producer) • A “drinker” (consumer) • Result: A mess! Pourer: while (true){ pour(); } Drinker(s): while (true){ drink(); }

  3. So, what do we want? Simple protocol: • Pourer pours only when cup is empty • Drinker drinks only when cup is full • Pourer: • while (true){ • if (!full){ • pour(); • full = true; • } • } Drinker(s): while (true){ if (full) { drink(); full = false; } }

  4. Ok, but… … what if we have two drinkers? • Both drinkers can drink at the same time! Drinker 1: while (true){ if (full) { drink(); full = false; } } Drinker 2: while (true){ if (full) { drink(); full = false; } } Need this to be atomic!

  5. Fine! So how can we do this? Use Semaphores! • A semaphore is an object used to synchronize multiple threads. • Two functions: • Wait() : willing • Signal() : release the lock • Both functions are guaranteed to be atomic

  6. Semaphore Example Clients arriving at a restaurant with only 10 seats. • Manager = Semaphore • Clients = Threads • 10 Seats = 10 Limited resources controlled using the semaphore.

  7. Semaphore Java Code class Semaphore { private int value; Semaphore (int value1) { value = value1; } public synchronized void Wait () { while( value <= 0 ) { try { wait (); } catch (InterruptedException e) { }; } value--; } public synchronized void Signal () { ++value; notify (); } }

  8. Multiple drinkers? No problem! • Using semaphores, we can make sure that only one drinker can ever drink at one time • Important: Wait() and Signal() are guaranteed to be atomic! Main: // Semaphore initialization Semaphore cup; cup = new Semaphore(1); Drinker i: while (true){ sem.Wait(); drink(); sem.Signal(); }

  9. Programming Assignment 2 Overview of the Problems: • The run() of Acquire and Release are not critical sections, hence they could leave Block in an inconsistent internal state • Acquires are not to run before the Releases complete

  10. To make matters worse… Not only: • are the run() functions not mutually exclusive – yields are inserted to force it to go wrong! • must the Acquires wait for the Releases to finish – the Acquires are put on the ready queue first! Ready Queue after all threads are created: main > A1 > A2 > R1 > R2

  11. “yield()s at crucial junctures” • These explicityield()’s represent what could be a time-slice context-switch in a “real-world” environment ++Block.top; ReleaseBlock : yield (); (push) Block.stack[Block.top] = block ; block = Block.stack[Block.top]; AcquireBlock: yield (); (pop) --Block.top;

  12. Semaphore Initial Values Note that the mutex and semaphores are initialized to different values: • The mutex is initialized to one to allow only one thread into the critical section at any time • The ‘prisem’ semaphores are initialized to zero to allow no Acquires to run (initially)

  13. Finally - Assignment Solution!!! Yeah right! • “Use the mutual-exclusion semaphore to make ‘acquire’ and ‘release’ atomic” • “Use the two ‘prisem’ semaphores to enforce the ordering that all ReleaseBlock threads must complete before any AcquireBlock threads can begin.”

More Related