Presentation is loading. Please wait.

Presentation is loading. Please wait.

Monitors, Condition Variables, and Readers-Writers

Similar presentations


Presentation on theme: "Monitors, Condition Variables, and Readers-Writers"— Presentation transcript:

1 Monitors, Condition Variables, and Readers-Writers
Mark Stanovich Operating Systems COP 4610

2 Motivation for Monitors
Semaphores are a big step from the low-level loads and stores However, semaphores are used for both mutual exclusion and scheduling The idea of monitors is to separate these two concerns

3 Monitor Defined Monitor: a lock + condition variables
Lock: provides mutual exclusion to shared data Condition variable: provides a queue for waiting threads inside a critical section

4 Locks A lock provides two operations: Lock::Acquire() Lock::Release()
Wait until the lock is free, then grab it Lock::Release() Unlock, wake up anyone waiting to Acquire A lock is initially free

5 More on Locks Always acquire a lock before accessing a shared data structure Always release the lock after finishing with the shared data structure

6 An Example of Using Locks
AddToBuffer() { Lock.Acquire(); // put 1 item to the buffer Lock.Release(); } RemoveFromBuffer() { // if something in the buffer // remove 1 item form the buffer return item;

7 Condition Variables We need additional mechanisms to wait inside locked regions However, holding the lock while waiting prevents other threads from entering the locked region Condition variables make it possible to sleep inside a critical section Atomically release the lock & go to sleep

8 Condition Variables Each condition variable
Consists of a queue of threads Provides three operations Wait(); Atomically release the lock and go to sleep Reacquire lock on return Signal(); Wake up one waiting thread, if any Broadcast(); Wake up all waiting threads

9 Condition Variables Note
The three operations can only be used inside locked regions

10 An Example of Using Condition Variables
AddToBuffer() { lock.Acquire(); // put 1 item to the buffer condition.Broadcast(&lock); // move threads from the // wait queue to the ready queue // do something else lock.Release(); } RemoveFromBuffer() { while nothing in the buffer { condition.Wait(&lock); // implicit lock release // implicit lock acquire return item;

11 Hoare vs. Mesa Monitors Hoare Monitors (used in most textbooks)
Signal() transfers the CPU directly to a waiting thread

12 Mesa vs. Hoare Monitors Mesa Monitors (used in most real operating systems) Signal() only puts a waiting thread on the scheduler’s ready queue By the time the waken thread gets the CPU, the waiting condition may no longer be true and needs to be retested

13 Readers-Writers Problem
Commonly seen in database applications Readers never modify the database Writers read and modify the database We want one writer at a time, but many readers at the same time

14 Constraints A reader should wait when a writer is accessing or waiting for the database Condition okToRead A write should wait when there is a reader or writer accessing the database Condition okToWrite A reader or a writer should wait when someone is modifying global states Lock lock

15 Basic Structure of the Solution
Reader Wait until no writers Access database Wake up waiting writers Writer Wait until no active readers or writers Wake up waiting readers or writers

16 Developing the Solution
Global states: activeReaders = 0; activeWriters = 0; waitingReaders = 0; waitingWriters = 0; Condition okToRead = NULL; Condition okToWrite = NULL; Lock lock = FREE;

17 Put in Locks and Some Global States
Reader() { lock.Acquire(); ++activeReaders; lock.Release(); // access database --activeReaders; } Writer() { lock.Acquire(); ++activeWriters; lock.Release(); // access database --activeWriters; }

18 Add the Wait Condition for Reader
lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; Writer() { lock.Acquire(); ++activeWriters; lock.Release(); // access database --activeWriters; }

19 Add the Wait Condition for Writer
Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters;

20 Add the Signal Condition for Reader
lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters;

21 Add the Signal Condition for Writer
Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

22 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

23 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

24 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

25 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

26 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

27 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

28 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

29 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

30 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

31 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

32 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

33 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

34 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

35 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

36 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

37 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

38 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

39 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

40 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

41 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

42 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

43 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

44 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

45 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

46 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

47 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

48 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

49 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

50 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

51 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

52 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

53 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

54 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

55 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

56 Code Demonstration Reader() { lock.Acquire();
while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock);

57 Semaphores vs. Monitors
Can we implement monitors with semaphores? Wait() { P(s); } Signal() { V(s);

58 Semaphores vs. Monitors
Not quite… Condition variables only work inside a lock Using semaphores inside a lock may deadlock

59 Semaphores vs. Monitors
Condition variables have no history, but semaphores have Signal() with an empty queue does nothing A subsequent Wait() will wait V() increments semaphore A subsequent P() will not wait


Download ppt "Monitors, Condition Variables, and Readers-Writers"

Similar presentations


Ads by Google