![Page 1: Monitors, Condition Variables, and Readers-Writers](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/1.jpg)
Monitors, Condition Variables, and Readers-Writers
![Page 2: Monitors, Condition Variables, and Readers-Writers](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/2.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/3.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/4.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/5.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/6.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/7.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/8.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/9.jpg)
Condition Variables
Note The three operations can only be used inside locked regions
![Page 10: Monitors, Condition Variables, and Readers-Writers](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/10.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/11.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/12.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/13.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/14.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/15.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/16.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/17.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/18.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/19.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/20.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/21.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/22.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/23.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/24.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/25.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/26.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/27.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/28.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/29.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/30.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/31.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/32.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/33.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/34.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/35.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/36.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/37.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/38.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/39.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/40.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/41.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/42.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/43.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/44.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/45.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/46.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/47.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/48.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/49.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/50.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/51.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/52.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/53.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/54.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/55.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/56.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/57.jpg)
Semaphores vs. Monitors
Can we implement monitors with semaphores?Wait() { P(s);
}Signal() { V(s);
}
![Page 58: Monitors, Condition Variables, and Readers-Writers](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/58.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062501/56815dc7550346895dcbf369/html5/thumbnails/59.jpg)
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