monitors, condition variables, and readers-writers

59
Monitors, Condition Variables, and Readers-Writers

Upload: kolton

Post on 12-Feb-2016

66 views

Category:

Documents


0 download

DESCRIPTION

Monitors, Condition Variables, and Readers-Writers. Motivation for Monitors. Semaphores are a big step from the low-level loads and stores However, semaphores are used for both mutual exclusion and synchronization The idea of monitors is to separate these two concerns. Monitor Defined. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Monitors, Condition Variables, and Readers-Writers

Monitors, Condition Variables, and Readers-Writers

Page 2: Monitors, Condition Variables, and Readers-Writers

Motivation for Monitors

Semaphores are a big step from the low-level loads and storesHowever, semaphores are used for both mutual exclusion and synchronizationThe idea of monitors is to separate these two concerns

Page 3: Monitors, Condition Variables, and Readers-Writers

Monitor Defined

Monitor: a lock + condition variablesLock: provides mutual exclusion to shared dataCondition variable: provides a queue for waiting threads inside a critical section

Enabling synchronization between processes.

Page 4: Monitors, Condition Variables, and Readers-Writers

Locks

A lock provides two operations:Lock::Acquire()

Wait until the lock is free, then grab it

Lock::Release()Unlock, wake up anyone waiting to Acquire

A lock is initially free

Page 5: Monitors, Condition Variables, and Readers-Writers

More on Locks

Always acquire a lock before accessing a shared data structureAlways release the lock after finishing with the shared data structure

Page 6: Monitors, Condition Variables, and Readers-Writers

An Example of Using Locks

AddToQueue() {Lock.Acquire();// put 1 item to the queueLock.Release();

}

RemoveFromQueue() {Lock.Acquire();// if something on the queue// remove 1 item form the queueLock.Release();return item;

}

Page 7: Monitors, Condition Variables, and Readers-Writers

Condition Variables

We need additional mechanisms to wait inside locked regionsHowever, holding the lock while waiting prevents other threads from entering the locked regionCondition variables make it possible to sleep inside a critical section

Atomically release the lock & go to sleep

Page 8: Monitors, Condition Variables, and Readers-Writers

Condition Variables

Each condition variable Consists of a queue of threadsProvides 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

Page 9: Monitors, Condition Variables, and Readers-Writers

Condition Variables

Note The three operations can only be used inside locked regions

Page 10: Monitors, Condition Variables, and Readers-Writers

An Example of Using Condition VariablesAddToQueue() {

lock.Acquire();// put 1 item to the queuecondition.Signal(&lock);lock.Release();

}

RemoveFromQueue() {lock.Acquire();while nothing on queue

condition.Wait(&lock);lock.Release();return item;

}

Page 11: Monitors, Condition Variables, and Readers-Writers

Hoare vs. Mesa Monitors

Hoare Monitors (used in most textbooks)

Signal() transfers the CPU directly to a waiting thread

Page 12: Monitors, Condition Variables, and Readers-Writers

Mesa vs. Hoare Monitors

Mesa Monitors (used in most real operating systems)

Signal() only puts a waiting thread on the scheduler’s ready queueBy the time the waken thread gets the CPU, the waiting condition may no longer be true and needs to be retested

Page 13: Monitors, Condition Variables, and Readers-Writers

Readers-Writers Problem

Commonly seen in database applications

Readers never modify the databaseWriters read and modify the database

We want one writer at a time, but many readers at the same time

Page 14: Monitors, Condition Variables, and Readers-Writers

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

Page 15: Monitors, Condition Variables, and Readers-Writers

Basic Structure of the Solution

ReaderWait until no writersAccess databaseWake up waiting writers

WriterWait until no active readers or writersAccess databaseWake up waiting readers or writers

Page 16: Monitors, Condition Variables, and Readers-Writers

Developing the Solution

Global states:

activeReaders = 0;activeWriters = 0;waitingReaders = 0;waitingWriters = 0;

Condition okToRead = NULL;Condition okToWrite = NULL;Lock lock = FREE;

Page 17: Monitors, Condition Variables, and Readers-Writers

Put in Locks and Some Global StatesReader() { lock.Acquire(); ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; lock.Release();}

Writer() { lock.Acquire(); ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; lock.Release();}

Page 18: Monitors, Condition Variables, and Readers-Writers

Add the Wait Condition for Reader

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

Writer() { lock.Acquire(); ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; lock.Release();}

Page 19: Monitors, Condition Variables, and Readers-Writers

Add the Wait Condition for Writer

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

Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; lock.Release();}

Page 20: Monitors, Condition Variables, and Readers-Writers

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

Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; lock.Release();}

Page 21: Monitors, Condition Variables, and Readers-Writers

Add the Signal Condition for Writer

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

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

Page 22: Monitors, Condition Variables, and Readers-Writers

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

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

Page 23: Monitors, Condition Variables, and Readers-Writers

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

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

Page 24: Monitors, Condition Variables, and Readers-Writers

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

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

Page 25: Monitors, Condition Variables, and Readers-Writers

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

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

Page 26: Monitors, Condition Variables, and Readers-Writers

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

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

Page 27: Monitors, Condition Variables, and Readers-Writers

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

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

Page 28: Monitors, Condition Variables, and Readers-Writers

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

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

Page 29: Monitors, Condition Variables, and Readers-Writers

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

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

Page 30: Monitors, Condition Variables, and Readers-Writers

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

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

Page 31: Monitors, Condition Variables, and Readers-Writers

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

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

Page 32: Monitors, Condition Variables, and Readers-Writers

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

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

Page 33: Monitors, Condition Variables, and Readers-Writers

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

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

Page 34: Monitors, Condition Variables, and Readers-Writers

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

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

Page 35: Monitors, Condition Variables, and Readers-Writers

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

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

Page 36: Monitors, Condition Variables, and Readers-Writers

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

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

Page 37: Monitors, Condition Variables, and Readers-Writers

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

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

Page 38: Monitors, Condition Variables, and Readers-Writers

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

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

Page 39: Monitors, Condition Variables, and Readers-Writers

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

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

Page 40: Monitors, Condition Variables, and Readers-Writers

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

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

Page 41: Monitors, Condition Variables, and Readers-Writers

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

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

Page 42: Monitors, Condition Variables, and Readers-Writers

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

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

Page 43: Monitors, Condition Variables, and Readers-Writers

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

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

Page 44: Monitors, Condition Variables, and Readers-Writers

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

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

Page 45: Monitors, Condition Variables, and Readers-Writers

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

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

Page 46: Monitors, Condition Variables, and Readers-Writers

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

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

Page 47: Monitors, Condition Variables, and Readers-Writers

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

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

Page 48: Monitors, Condition Variables, and Readers-Writers

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

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

Page 49: Monitors, Condition Variables, and Readers-Writers

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

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

Page 50: Monitors, Condition Variables, and Readers-Writers

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

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

Page 51: Monitors, Condition Variables, and Readers-Writers

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

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

Page 52: Monitors, Condition Variables, and Readers-Writers

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

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

Page 53: Monitors, Condition Variables, and Readers-Writers

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

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

Page 54: Monitors, Condition Variables, and Readers-Writers

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

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

Page 55: Monitors, Condition Variables, and Readers-Writers

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

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

Page 56: Monitors, Condition Variables, and Readers-Writers

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

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

Page 57: Monitors, Condition Variables, and Readers-Writers

Semaphores vs. Monitors

Can we implement monitors with semaphores?Wait() { P(s);

}Signal() { V(s);

}

Page 58: Monitors, Condition Variables, and Readers-Writers

Semaphores vs. Monitors

Not quite…Condition variables only work inside a lock

Using semaphores inside a lock may deadlock

Page 59: Monitors, Condition Variables, and Readers-Writers

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 semaphoreA subsequent P() will not wait