Presentation is loading. Please wait.

Presentation is loading. Please wait.

Tutorial 5 Even More Synchronization! presented by: Antonio Maiorano Paul Di Marco.

Similar presentations


Presentation on theme: "Tutorial 5 Even More Synchronization! presented by: Antonio Maiorano Paul Di Marco."— Presentation transcript:

1 Tutorial 5 Even More Synchronization! presented by: Antonio Maiorano Paul Di Marco

2 Quick Recap When multiple threads share resources, we need a way to synchronize access to these resources Recall the coffee example with pourer and drinker Solution: Use semaphores!

3 Alternatives to Semaphores Semaphores are great, but they can be difficult to use when solving certain problems We will look at alternatives to semaphores Note: These alternatives are more convenient, though semaphores can still be used to solve these problems

4 Problem 1 2 drummers (threads) each with his/her own drum set Only 2 drumsticks: drumStick1 and drumStick2 (shared resources) Both drummers want to play, and to play, a drummer needs two drumsticks

5 One solution… Drummer 1: drumStick1.Wait(); drumStick2.Wait(); PlayDrums(); drumStick2.Signal(); drumStick1.Signal(); Drummer 2: drumStick1.Wait(); drumStick2.Wait(); PlayDrums(); drumStick2.Signal(); drumStick1.Signal(); Semaphore drumStick1 = new Semaphore(1); Semaphore drumStick2 = new Semaphore(2); This works, but…

6 But what if… Drummer 1: drumStick1.Wait(); drumStick2.Wait(); PlayDrums(); drumStick2.Signal(); drumStick1.Signal(); Drummer 2: drumStick2.Wait(); drumStick1.Wait(); PlayDrums(); drumStick1.Signal(); drumStick2.Signal(); Potential deadlock! Problem: can’t rely on programmers to obtain semaphores in the same order

7 Alternative: AND Synchronization Two functions: –WaitMulti(S1, S2, …,Sn) : Blocks calling thread until all semaphores are available –SignalMulti(S1, S2, …, Sn) : Releases all semaphores Easy to implement See Java code: MultiSemTest.java

8 Drummers… one more time! Drummer 1: drumSticks.WaitMulti(); PlayDrums(); drumSticks.SignalMulti(); Drummer 2: drumSticks.WaitMulti(); PlayDrums(); drumSticks.SignalMulti(); Semaphore drumStick1 = new Semaphore(1); Semaphore drumStick2 = new Semaphore(2); MultiSemaphore drumSticks; drumSticks = new MultiSemaphore(drumStick1, drumStick2); Problem solved!

9 Problem 2 Global keyboard state object : Know when keys are pressed Threads: ask keyboard state object when a key has been pressed Threads may start at any time

10 One solution… Operating System thread:... if (keyPressed = ‘A’) keyA.Signal();... User thread:... // Wait for ‘A’ key to be // pressed before continuing keyA.Wait();... Semaphore keyA = new Semaphore(0); // Initially not pressed This works sometimes…

11 What’s the problem? Only one thread will react upon key press If a thread starts after the key has been pressed, the Wait() call will return immediately The semaphore is passive: it does not take timing into account We need an active semaphore…

12 Alternative: Events Events are active semaphores with its functions defined as: –Wait() : Block until event occurs; calling thread is added to the event’s waiting queue. –Signal() : Unblock all threads on event’s waiting queue; remove them from the queue. See Java code: EventTest.java

13 One more time… Operating System thread:... if (keyPressed = ‘A’) keyA.Signal();... User thread:... // Wait for ‘A’ key to be // pressed before continuing keyA.Wait();... Event keyA = new Semaphore(0); // Initially not pressed Only diff!

14 Monitors A monitor is an Abstract Data Type – like a class The key importance of a monitor is that only one function can be accessed at a time An important property of ADTs for use with monitors is separation of interface and implementation

15 Interface / Implementation Have a public interface to the class while maintaining the implementation private: Prevents use of internal structures Allows the implementation to change while keeping the same interface Allows for control of how the object is used Enforced interface allows for proving properties about its behaviour

16 Monitor Analogy A monitor can be thought of as a class where each function is a critical section The monitor thus would have a mutex as a private data member, and Each function would thus call mutex.Wait() before executing, and mutex.Signal() before exiting.

17 In Java… A monitor can be implemented as we just described, or As a class where all of the methods are “ synchronized ”, where Java does the work for you

18 Simple Monitor monitor SharedBalance { private int balance; public SharedBalance(int amt) {balance = amt;} public credit(int amt) {balance += amt;} public debit(int amt) {balance –= amt;} }

19 Readers – Writers Problem We have many readers and many writers –Readers want to read a resource –Writers want to write to a resource Rules: –Multiple readers are allowed –One writer can write at a time –No readers can read when a writer is writing

20 Building Our Solution Before the reader or writer reads from the resource, it calls the its “start” method The “start” methods ensure that the “coast is clear”; that it is fine to continue to read from/write to the resource The “finish” methods allow the next thread to read or write

21 Our Monitor We want to solve the problem with a monitor, so it will need to keep track of: –int numReaders = 0: number of readers currently reading –int numWriters = 0: number of writers currently writing / waiting to write –boolean busy = false: is a writer busy?

22 The Readers and Writers reader() { while (true){ // … mon.startRead(); // read the resource mon.finishRead(); // … } writer() { while (true) { // … mon.startWrite(); // write the resource mon.finishWrite(); // … }

23 Our Solution // reader methods startRead() { while (numWriters != 0); ++numReaders; } finishRead() { --numReaders; } // writer methods startWrite() { ++numWriters; while (busy || numReaders > 0); busy = true; } finishWrite() { --numWriters; busy = false; }

24 The Problem With Our Solution While a reader/writer is executing it’s “start” in the monitor, no other processes are allowed in!!! We have to look further for our solution… Condition variables are used when: –a thread running in a monitor –encounters a condition that is not satisfied, –which can only be satisfied by another thread

25 Condition Variables This is exactly what we need! Condition Variables are an extension of Events to the concept of monitors –It temporarily blocks current thread, –Handing over “ownership” of the monitor to another thread – to do some work that will make the condition true –The original thread regains “ownership” of monitor later on…

26 Regaining the Monitor What happens on a call to signal() depends on the semantics used Hoare’s semantics: –Signaling thread (S) is immediately interrupted and monitor is given back to a blocked thread (B) –Thread S resumes (in the monitor) when B finishes using the monitor

27 And Another Way… Hansen’s sematics are not immediate: –Signal is “saved” –A blocked thread will wake up only when the signaling thread finishes with the monitor * The blocked thread must always verify the condition again upon waking up, since some time has elapsed since the signal() was called –This results in less context switches, increasing system performance

28 How Do We Use Them? Condition variables have three methods: –wait(): block on a variable, give up monitor –signal(): wake up a thread blocked on this –queue(): ask if are there any threads blocked on this variable - to be used as part of the condition In Java, they correspond to the usage, within “ synchronized ” objects, of wait() and signal() – although there is no queue()

29 Return to Readers – Writers Now that we know about condition variables, we can solve this problem easily We now have the following variables: –int numReaders = 0 (same as before) –boolean busy = false (same as before) –Condition Variables okToRd, okToWr Solution will use Hoare’s semantics

30 The Final Solution // reader methods startRead() { while (busy || okToWr.queue()) okToRead.wait(); ++numReaders; } finishRead() { --numReaders; if (numReaders == 0) okToWr.signal() } // writer methods startWrite() { ++numWriters; while (numReaders != 0 || busy) okToWr.wait(); busy = true; } finishWrite() { busy = false; if (okToWr.queue()) okToWr.signal(); else okToRead.signal(); }


Download ppt "Tutorial 5 Even More Synchronization! presented by: Antonio Maiorano Paul Di Marco."

Similar presentations


Ads by Google