How to implement Monitors using Semaphores
Monitors
Monitor is a type of synchronization device designed to solve difficulties caused by semaphores, such as timing errors. Monitors are the type of data types that are abstract by nature and contain common data variables and operations. A process cannot directly access shared data variables, so processes are required to allow one process to access shared data variables at a time.
In a monitor, only one process can be active at a time. Other processes that want access to the shared variable in the monitor must be queued and access is granted only after the prior process has released the shared variable.
Semaphores
A semaphore is a signaling technology that allows another thread to signal a thread that is waiting for a semaphore. This is not the same as a mutex, which can only be signaled by the thread that implements the wait function. For process synchronization, a semaphore employs two atomic operations: wait and signal. If the value of its input A is positive, the wait operation decrements it. If A is negative or zero then no operation is performed.
wait(A)
{
while (A<=0);
A--;
}
The value of the signal operation's parameter A is increased.
signal(A)
{ A++;
}
Counting semaphores and binary semaphores are the two most common forms of semaphores. Counting Semaphores have an unconstrained value domain and are integer value semaphores. The amount of accessible resources is represented by the semaphore count, which is used to coordinate resource access. Binary semaphores are similar to counting semaphores, except that their values are limited to 0 and 1. When the semaphore is 1, the wait action succeeds, and when the semaphore is 0, the signal operation succeeds.
Implementation
A semaphore mutex (which is initialised to 1) is given for each monitor to implement monitor utilising semaphores. Before entering the monitor, a process must perform wait(mutex), and after exiting the monitor, signal(mutex) must be executed. Because a signalling process must wait until the resumed process departs or waits, an extra semaphore is added next, which is set to 0. The signalling mechanisms can exploit this to put themselves in a state of suspension. The number of processes suspended on next is counted using the integer variable next count. As a result, each external function A is substituted with
wait(mutex);
...
body of A
...
if (next_count > 0)
signal(next);
else
signal(mutex);
Within a monitor, mutual exclusion is guaranteed. Let's have a look at how condition variables are implemented. We add a semaphore i_sem and an integer variable i count for each condition i, both of which are initialised to 0. The i.wait() method may now be implemented as:
i_count++;
if (next_count > 0){
signal(next);
}
else {
signal(mutex);
}
wait(i_sem);
i_count--;
The operation i.signal() can be implemented in the following way:
if (i _count > 0){
next_count++;
signal(i_sem);
wait(next);
next_count--;
}