14 - Drexel University

Database reader/writer problem
CS 361 Concurrent programming
Drexel University
Fall 2004
Lecture 14
©Bruce Char and Vera Zaychik. All rights reserved by the author.
Permission is given to students enrolled in CS361 Fall 2004 to
reproduce these notes for their own use.
page 1
• The readers and writers problem: readers may read a
database simultaneously as long as no writer writes
• Only one writer at a time may write (if there are no active
readers).
• Attain: maximal parallelism (readers may read
simultaneously if there is no writing), data integrity (only
one writer at a time if no readers are reading).
• Possible additional goal: avoid writer starvation (locked
out of writing because readers are always coming along to
read).
page 2
Database reader/writer solution
import Utilities.*;
import Synchronization.*;
class Database extends MyObject {
private int numReaders = 0;
private BinarySemaphore mutex = new BinarySemaphore(1);
private BinarySemaphore ok = new BinarySemaphore(1);
public Database() { super("Database"); }
Reader code
public void startRead(int i) {
P(mutex);
numReaders++;
if (numReaders == 1) {
System.out.println("age=" + age() + " reader " + i
+ " waiting to read, numReaders=" + numReaders);
P(ok);
}
System.out.println("
age=" + age() + " reader " + i
+ " has begun reading, numReaders=" + numReaders);
V(mutex);
}
public void endRead(int i) {
P(mutex);
numReaders--;
System.out.println("
age=" + age() + " reader " + i
+ " finished reading, numReaders=" + numReaders);
if (numReaders == 0) V(ok);
V(mutex);
} page 4
page 3
Writer code
public void startWrite(int i) {
P(ok);
System.out.println("
age=" + age() + " WRITER " + i
+ " has begun Writing");
}
public void endWrite(int i) {
System.out.println("
age=" + age() + " WRITER " + i
+ " has finished Writing");
V(ok);
}
Notes on reader/writer solution
– Only the first reader should lock the “ok” lock.
The last reader should unlock it when it finishes
its read. Then the
– Writers can write. Starvation of writers might
occur.
}
page 5
page 6
1
Preventing starvation of writers
• “Serialization”
– Use a queue for all (makes any reader wait who arrives after a
writer).
• “Platooning”
– Use a queue for waiting threads, and have a separate “active
group” of threads.
– While readers in the active group are working, writers wait in the
queue.
– If a writer is waiting, any later reader must wait in the queue.
– After a writer finishes, it sweeps all the waiting readers into the
active group (even if they have arrived after the next writer).
– Avoids starvation but increases parallelism.
page 7
How do you do this?
• Hint: try time stamping a reader’s or
writer’s arrival to keep track of who should
proceed or not.
page 8
A problem to solve
Baboons, cont.
• Baboons crossing a canyon
• A canyon cuts through the territory of a colony of
baboons. the baboons use a rope stretching across
the canyon to cross from one side to the other. the
rope is strong enough to permit any number of
baboons to cross in the same direction at the same
time, but is too thin to allow baboons to cross in
both directions at once.
• So a baboon that wants to cross from west to east
must wait until all westward moving baboons have
finished and the rope is free, and vice versa.
• If the rope is being used by westward-moving
baboons, then other baboons may start to cross
from east to west no matter how many eastwardmoving baboons are waiting.
page 9
page 10
How to solve it
• First, write your program without worrying
about a series of eastward-moving baboons
holding up the waiting westward-moving
ones (i.e. don’t worry about starvation).
• Then modify your program so that it is fair
and there is no starvation. Use serialization
or platooning to do this (or another method
of your invention).
page 11
Deadlock with semaphores
– Deadlock can happen through a typo:
– P(s); critical section; P(s);
page 12
2
Another way to get into trouble
Thread #1
P(S);
…
P(T); … V(T);
…
V(S);
A: P(S) succeeds
B:P(T) succeeds
A: blocks on P(T)
B: blocks on P(S).
page 13
Thread #2
P(T);
…
P(S);..V(S);
…
V(T);
How to avoid the trouble of
interlocking semaphores
• One way to avoid deadlock on semaphores is to assign a global order
to all semaphores and require that all threads decrement (P operation)
semaphores according to global order. “It is impossible for a set of
threads to develop in which each thread is blocked waiting for a
semaphore to be released (incremented) while holding another
semaphore.” Why?
• Suppose all n threads are blocked. They are using semaphores S1, S2,
S3, … Sn. Look at these threads in the total ordering. Let the thread
that’s last in the total ordering be Sk. Then someone else must have
caused Sk’s value to become zero by doing a P(Sk) operation. But if
that thread is blocked itself, it must be doing a P(Sl),where l is not k.
But how can that be? It must have done a P(Sk) before the current
P(Sl), and that violates the rule that you do P(Sk) after P(Sl).
• Endpageof14proof.
3