CS 3733 Operating Systems Notes: Monitors
Get Dining Philosophers Monitor Pseudocode (book)
Get Dining Philosophers Monitor Pseudocode (Mine)
Get Bounded Buffer in Java
Monitors were developed in the 1970s to make it easier to avoid deadlocks.
- A monitor is a collection of procedures, variables, and
data structures grouped together.
- Processes can call the monitor procedures but cannot access the
internal data structures.
- Only one process at a time may be be active in a monitor.
Active in a monitor means in ready queue or CPU with the program counter
somewhere in a monitor method.
- A monitor is a language construct.
Compare this with semaphores, which are usually an OS construct.
- The compiler usually enforces mutual exclusion.
- Condition variables allow for blocking and unblocking.
- cv.wait() blocks a process.
The process is said to be waiting for (or waiting on) the condition variable cv.
- cv.signal() (also called cv.notify)
unblocks a process waiting for the
condition variable cv.
When this occurs, we need to still require that only one process
is active in the monitor. This can be done in several ways:
- on some systems the old process leaves the monitor
and the new one enters
- on some systems the signal must be the last statement
executed inside the monitor.
- on some systems the old process will block until the monitor
is available again.
- If a condition variable is signaled with nobody waiting,
the signal is lost.
Compare this with semaphores, in which a signal will allow a process
that executes a wait in the future to no block.
- You should not think of a condition variable as a variable in the
traditional sense.
It does not have a value.
Think of it as an object in the OOP sense.
It has two methods, wait and signal that manipulate
the calling process.
An example: Dining Philosophers
- 5 philosophers sit at a round table with 5 plates of rice and 5 chopsticks.
- 2 chopsticks are require to eat.
- Each philosopher is in one of the states:
Dining Philosophers
Look at code for almost solving this using monitor pseudocode.
Note that this "solution" allows starvation.
Monitor Implementation
Monitors are implemented by using queues to keep track of the processes
attempting to become active int he monitor.
To be active, a monitor must obtain a lock to allow it to execute the
monitor code.
Processes that are blocked are put in a queue of processes waiting for an
unblocking event to occur.
These are the queues that might be used:
- The entry queue contains processes attempting to call a monitor
procedure from outside the monitor.
Each monitor has one entry queue.
- The signaller queue contains processes processes that have executed
a notify operation.
Each monitor has at most one signaller queue.
In some implementations, a notify leaves the process active and no
signaller queue is needed.
- The waiting queue contains processes that have been awakened by
a notify operation.
Each monitor has one waiting queue.
- Condition variable queues contain processes that have executed
a condition variable wait operation.
There is one such queue for each condition variable.
The relative priorities of these queues determines the operation of the
monitor implementation.
The queues associated with a monitor that does not have a signaller queue.
The lock becomes available when the active process executes a wait or leaves
the monitor.
Additional information about monitors can be found in:
Starving Philosophers: Experimentation with Monitor Synchronization.
This describes a monitor
simulator
for the Dining Philosophers Problem.
One modern language that uses monitors is Java.
- Each object has its own monitor.
- Methods are put in the monitor using the synchronized keyword.
- Each monitor has one condition variable.
- The methods on the condition variables are: wait(),
notify(), and notifyAll().
- Since there is only one condition variable, the condition variable
is not explicitly specified.