Reader-Writers solution using Monitors

16 Aug, 2019
Prerequisite – Process Synchronization, Monitors, Readers-Writers ProblemConsidering a shared Database our objectives are:
Readers can access database only when there are no writers.
Writers can access database only when there are no readers or writers.
Only one thread can manipulate the state variables at a time.
Basic structure of a solution –
Reader()
   Wait until no writers
   Access database
   Check out – wake up a waiting writer
Writer()
   Wait until no active readers or writers
   Access database
   Check out – wake up waiting readers or writer

–Now let’s suppose that a writer is active and a mixture of readers and writers now show up.Who should get in next?–Or suppose that a writer is waiting and an endless of stream of readers keep showing up.Would it be fair for them to become active?So we’ll implement a kind of back-and-forth form of fairness:
Once a reader is waiting, readers will get in next.
If a writer is waiting, one writer will get in next.
Implementation of the solution using monitors:-
The methods should be executed with mutual exclusion i.e. At each point in time, at most one thread may be executing any of its methods.Monitors also provide a mechanism for threads to temporarily give up exclusive access, in order to wait for some condition to be met, before regaining exclusive access and resuming their task.Monitors also have a mechanism for signaling other threads that such conditions have been met.So in this implementation only mutual exclusion is not enough. Threads attempting an operation may need to wait until some assertion P holds true.While a thread is waiting upon a condition variable, that thread is not considered to occupy the monitor, and so other threads may enter the monitor to change the monitor’s state.
The methods should be executed with mutual exclusion i.e. At each point in time, at most one thread may be executing any of its methods.
Monitors also provide a mechanism for threads to temporarily give up exclusive access, in order to wait for some condition to be met, before regaining exclusive access and resuming their task.
Monitors also have a mechanism for signaling other threads that such conditions have been met.
So in this implementation only mutual exclusion is not enough. Threads attempting an operation may need to wait until some assertion P holds true.
While a thread is waiting upon a condition variable, that thread is not considered to occupy the monitor, and so other threads may enter the monitor to change the monitor’s state.
Code –
// STATE VARIABLES// Number of active readers; initially = 0int NReaders = 0;  // Number of waiting readers; initially = 0int WaitingReaders = 0;  // Number of active writers; initially = 0int NWriters = 0;  // Number of waiting writers; initially = 0int WaitingWriters = 0;  Condition canRead = NULL;Condition canWrite = NULL;  Void BeginWrite(){      // A writer can enter if there are no other    // active writers and no readers are waiting    if (NWriters == 1 || NReaders > 0) {          ++WaitingWriters;        wait(CanWrite);        --WaitingWriters;    }      NWriters = 1;}  Void EndWrite(){      NWriters = 0;      // Checks to see if any readers are waiting    if (WaitingReaders)          Signal(CanRead);      else          Signal(CanWrite);}  Void BeginRead(){      // A reader can enter if there are no writers    // active or waiting, so we can have    // many readers active all at once    if (NWriters == 1 || WaitingWriters > 0) {          ++WaitingReaders;          // Otherwise, a reader waits (maybe many do)        Wait(CanRead);          --WaitingReaders;    }      ++NReaders;    Signal(CanRead);}  Void EndRead(){      // When a reader finishes, if it was the last reader,    // it lets a writer in (if any is there).    if (--NReaders == 0)          Signal(CanWrite);}
Understanding the solution:-
It wants to be fair.
If a writer is waiting, readers queue up.If a reader (or another writer) is active or waiting, writers queue up.This is mostly fair, although once it lets a reader in, it lets ALL waiting readers in all at once, even if some showed up “after” other waiting writers.
If a writer is waiting, readers queue up.
If a reader (or another writer) is active or waiting, writers queue up.
This is mostly fair, although once it lets a reader in, it lets ALL waiting readers in all at once, even if some showed up “after” other waiting writers.
The code is “simplified” because we know there can only be one writer at a time.
It also takes advantage of the fact that signal is a no-op if nobody is waiting.
In the “EndWrite” code (it signals CanWrite without checking for waiting writers)In the EndRead code (same thing)In StartRead (signals CanRead at the end)
In the “EndWrite” code (it signals CanWrite without checking for waiting writers)
In the EndRead code (same thing)
In StartRead (signals CanRead at the end)
With Semaphores we never did have a “fair” solution of this sort. In fact it can be done but the code is quite tricky. Here the straightforward solution works in the desired way! Monitors are less error-prone and also easier to understand.
GATE CS
Operating Systems
Operating Systems
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Normal Forms in DBMS
Page Replacement Algorithms in Operating Systems
Inter Process Communication (IPC)
Differences between TCP and UDP
Introduction of Operating System - Set 1
Banker's Algorithm in Operating System
Page Replacement Algorithms in Operating Systems
Disk Scheduling Algorithms
File Allocation Methods
Paging in Operating System