Monitors
description
Transcript of Monitors
Monitors
A Problem with Semaphores
P(printer)
P(scanner)
- CS -
P1
P(scanner)
P(printer)
- CS -
P2
timerinterrupt
blocked blocked
mutexes
printer = -1scanner = 0
Consider the following scenario:
But if this occurs, then both processes will become deadlocked.
If there is a timer interrupt after the call to P(printer) but before P(scanner) in P1 then P2 will be able to start and call P(scanner).
Introducing Monitors
the term “monitor” (in regard to access control) coined by C.A.R. Hoare in 1974
all variables and functions for access control related to a specific data source are contained within a single structure
monitors act as “barriers” for data allowing access via programmer-defined functions
mutexes and calls to P() and V() previously scattered throughout code are no longer necessary
processes need no longer be aware of each other for access control; rather, they need only knowledge of monitor functions
R1 R2 Rn
W1 W2 Wn
Shared DataMonitor
Protection of Shared Data via Monitor
Reader and writer processes R and W are requiring access to shared data. Such access is controlled by a single monitor. (More on the readers/writers problem later.)
Monitor internals
process flow control is accomplished via calls to wait() and signal() that each take a condition variable as the parameter– wait(cond) suspends the calling process and places it into a queue– signal(cond) resumes the execution of an enqueued process
previously suspended by a call to wait(cond) think of a monitor as an object instantiated from a special class
– conditions are private data members of the monitor– wait() and signal() are protected functions inherently available
within all monitors– calls to wait() and signal() are made within the implementation of
user-defined public functions of a derived monitor
Monitor internals
by design, only one process may be inside of a monitor at any given instant
– parallel execution of monitor functions is impossible– eliminates possible race conditions while determining if a process
should wait any call to signal(cond) when no suspended processes are
enqueued is ignored– contrast this with calls to V(mutex) where mutex will be always
be incremented regardless of the number of calls to P(mutex)
Simple example:Mutually exclusive access via Monitor
monitor access
condition clear;bool inUse;
acquire()
if (inUse) wait(clear);inUse = true;
inUse = false;signal(clear);
release()
when some process P1 wants access to currently unshared data, it calls acquire() and is allowed to proceed into its critical section
if some different process P2 then calls acquire() prior to P1 releasing its hold, then P2 is suspended and enqueued upon the internal call to wait(clear) and will be blocked from reaching its critical section
upon P1 calling signal(clear) via release(), P2 is dequeued and allowed to continue execution
truefalse
Operations:
wait(clear)signal(clear)
acquire()
release()
monitor access
clear
Conditions
Demonstration of Exclusive Access via Monitor
P1P2
Entry Queue
access.acquire()
{critical section}
access.release()
P2
access.acquire()
{critical section}
access.release()
P1
Signal is sent by P1 to condition variable clear, thus dequeueing P2
As P1 has not yet released the resource, P2 is enqueued by its call to wait(clear).
No more processes!
inUse=
States
A more complicated example: “Readers and Writers problem” as a Monitor
must support multiple reader and writer processes
if a single reader enters a vacant data area, any or all readers (but not writers) may enter
if a writer enters a vacant data area, no readers or other writers may enter– writer must wait for readers and other writers to
vacate data area prior to entry
RaW.beginreading()
{critical section}
RaW.endreading()
Rn
processes
RaW.beginwriting()
{critical section}
RaW.endwriting()
Wn
“Readers and Writers” as a Monitor
monitor RaW
int readers;bool someonewriting;condition readallowed, writeallowed;
beginreading()
endreading()
beginwriting()
endwriting()
A solution to the “readers and writers” problem at a glance
Pseudocode Implementation
monitor RaWvar readers: integer;
someonewriting: boolean;readallowed, writeallowed: condition;
procedure beginreading {if someonewriting or queue(writeallowed)
then wait(readallowed);readers := readers + 1;signal(readallowed);}
procedure endwriting {readers := readers – 1;if readers = 0 then signal(writeallowed);}
procedure beginwriting {if (reader != 0 or someonewriting)
then wait(writeallowed);someonewriting := true; }
procedure endwriting {someonewriting := false;if queue(readallowed)
then signal(readallowed)else signal(writeallowed); }
{ readers := 0;someonewriting := false; } // end readers & writers