Readers-Writers Problem | Writers Preference Solution
Prerequisites — Readers-Writers Problem | Set 1 (Introduction and Readers Preference Solution), Semaphores in Process Synchronization
In Process-synchronization, there is a very classical synchronization problem named as Readers-writers problem. The problem has several sub-problems or variations all involving priorities, one of which is discussed in the above post. The second variation goes by the name Writer-priority readers-writers problem.
The set of variables used to solve the problem are:-
- The readers, which keeps the track of how many readers are there at a time.
- Mutex, protects the shared variables.
- Idle, is used to indicate the number of threads(reader or writer) in the critical section. If they’re no threads, then it should be 1, otherwise 0.
int readers = 0 //Keeps the count of readers idle = Semaphore (1) // 1 if no threads are present, else 0 mutex = Semaphore (1) //Mutex protects the shared counter
For the Semaphore variable,
wait() means “wait until a condition is true” and
signal() means that “signal that the condition is true”
readSwitch = Lightswitch () writeSwitch = Lightswitch () noReaders = Semaphore (1) noWriters = Semaphore (1)
First, let’s explore the scenario when Reader has priority over writer.
The problem statement: It states that, once a reader is ready, then readers may read the file. In other words, no reader should wait if the reader has access to the object, while the writer waits till the reader to complete it.
Solution when reader has priority over writer
- Writer requests entry to the critical section
- If allowed then, it holds noReaders, and writes. Else it waits in the queue, till wait() is true
- It exits the critical section
Here is the writer code:
idle.wait() //Waits till the critical section is empty. //Critical Section for the Writer idle.signal() //Signals that the critical section is empty.
Here, when the writer was in the critical section, no other thread( i.e. reader or writer) was present in the Critical section. First, a reader checks whether the critical section is empty or not. If empty, it proceeds there and bars the writer from entering.
- Reader requests for entry in the critical section.
- if allowed, then It holds noWriters, Since it holds the mutex, any subsequent readers queue on mutex. Subsequent readers can still enter
- Reader exits the critical section.
Here is the reader code :
readSwitch.lock ( noWriters ) //Locks the writer noReaders.wait () signaling // Waits till the reader exits the critical section //critical section for readers noReaders.signal () //Signals that reader has exited from the Critical section readSwitch.unlock (noWriters) // Unlocks the reader.
The problem statement: It requires that, once a writer is ready, that writer performs its write as soon as possible. In other words, if a writer is waiting to access the object, no new readers may start reading.
Solution when Writer has the Priority over Reader
- Reader requests the entry to the critical section
- If allowed, then,
- It holds noWriters, but it doesn’t hold noReaders. Thus if a writer arrives it can lock noReaders, which will cause subsequent readers to queue.
- Once the last reader exits, it signals noWriters, which allows the writers in the queue to proceed.
Here is the reader code:
noReaders.wait () readSwitch.lock ( noWriters ) // Locks the writers when readers enter the critical section noReaders.signal () //Signals that reader is in critical section //critical section for readers readSwitch . unlock ( noWriters ) //Once the reader exits the critical section, then the writer is unlocked.
- Writer requests the entry to the critical section.
- If allowed, then
- It holds both noReaders as well as noWriters. This ensures that no reader and no writer are in the critical section.
- If a reader is in the critical section, it holds noWriters, but it doesn’t hold noReaders. Thus if a writer arrives it can lock noReaders, which will cause subsequent readers to queue.
- Moreover, writeSwitch allows multiple writers to queue on noWriters, while locking the noReaders. Hence, many writers pass through the critical section without even signaling the noReaders
- Once the last writer leaves the critical section, then the only reader can enter the critical section
Here is the writer code:
writeSwitch . lock ( noReaders ) //Locks the reader noWriters . wait () // Waits till the writer is complete. //critical section for writers noWriters . signal () //Signals that writer has exited from the Critical section writeSwitch . unlock ( noReaders ) // Unlocks the reader.
But this implementation has a drawback, i.e. the readers may starve or may face long delays. To avoid starvation, monitors are used.
Please Login to comment...