Readings
You may wish to go through the readings after you have digested the
remainder of these lecture notes. It is very important that
you complete the readings and understand the solutions for the next
class, as we will be doing some exercises related to this material.
The Readers/Writers Problem
- consider a file that may be accessed simultaneously by multiple users
- can allow any number of readers at a time
- can only allow one writer at a time (no readers)
- how do we provide synchronization?
Solution #1: pg. 207
- first reader waits for all writers to complete
- any number of readers may access
- only one writer allowed to enter critical section
- writer must wait for all readers to complete
- problem: possible writer starvation
Solution #2: pg. 209
- when writer indicates intention to access, no new readers
may enter
int readCount = 0, writeCount = 0; /* # of readers, writers */
semaphore readBlock = 1; /* first writer blocks new readers */
semaphore writePending = 1; /* reader can proceed only
* if no writer pending */
semaphore writeBlock = 1; /* first reader blocks writers */
semaphore mutex1 = 1, mutex2 = 1; /* for variable update critical sections */
reader() {
while (TRUE) {
P(writePending); /* block if writer pending:
* occurs if previous reader doesn't
* make it past next line */
P(readBlock); /* block if writer active or pending */
P(mutex1); /* for variable update */
readCount++;
if (readCount == 1)
P(writeBlock); /* prevent writers from starting */
V(mutex1);
V(readBlock);
V(writePending);
access(resource); /* READ AWAY */
P(mutex1); /* for variable update */
readCount--;
if (readCount == 0)
V(writeBlock); /* signal writer it can start */
V(mutex1);
}
}
writer() {
while (TRUE) {
P(mutex2); /* for variable update */
writeCount++;
if (writeCount == 1)
P(readBlock); /* first writer arrives...
* don't allow any more readers */
V(mutex2);
P(writeBlock); /* block if reader(s) or
* other writer already active */
access(resource); /* WRITE AWAY */
V(writeBlock); /* next writer can start */
P(mutex2); /* for variable update */
writeCount--;
if (writeCount == 0) /* last writer is done */
V(readBlock); /* signal reader it can start */
V(mutex2);
}
}
Monitors
- monitors provide simplified paradigm for synchronization
- exactly same power as semaphores, but hide details in ADT
- ADT:
- caller only sees interface
- hidden implementation controls data structure
- monitor implementation likely uses semaphore to synchronize access
- only process can use monitor at a time; granted exclusive access
through the monitor semaphore
monitor myMon {
semaphore mutex = 1;
...
public:
proc_i(...) {
P(mutex);
V(mutex);
}
...
}
Solving the Readers/Writers problem with Monitors:
monitor ReaderWriter {
int numberOfReaders = 0;
int numberOfWriters = 0;
boolean busy = FALSE;
public:
startRead() {
while (numberOfWriters != 0);
numberOfReaders++;
}
finishRead() {
numberOfReaders--;
}
startWrite() {
numberOfWriters++;
while (busy || (numberOfReaders > 0));
busy = TRUE;
}
finishWrite() {
numberOfWriters--;
busy = FALSE;
}
}
- problem: look at implementation -- exclusive access granted to one process
- what happens when reader active and writer wants to start?
- pg. 230: solution requires waiting process to temporarily relinquish the monitor
while maintaining its intent to detect a state change in the monitor at a later time
- read pp. 230-233 for solution
- read pp. 235-236 for Monitor solution to Dining Philosopher's problem
- note that solution avoids deadlock but doesn't prevent starvation