- observe the pattern in produce-consumer syncnronization
- the stone appears to figure-eight between the empty and full semaphores
- note that "appears to" - it's a convention, not a property
- this pattern leads to the split binary semaphores
- split binary semaphore - a set
b
i of binary semaphores
- a split binary semaphore has effectively one stone
-
sum(i = 1 to
n ; b
i.cnt) <= 1
- a split binary semaphore ringing code provides mutual exclusion
- each component binary semaphore can represent a different
synchronization condition for the critical region
- readers-writers synchronization
- a common database problem
- an infinite sequence of readers and writers use a database
- readers don't change the database, writers do
- readers don't need exclusive access, writers do
- allow maximum performance with timely updates
- a simple mutex solution
semaphore mutex(1)
// reader or writer
mutex.lock()
// work the database
mutex.unlock()
- simple and obviously correct
- low performance, depends on unlock semantics
- a counting readers solution
int readers = 0
semaphore mutex(1)
// reader
<nr++ ; if (nr == 1) mutex.lock()>
// work the database
<nr-- ; if (nr == 0) mutex.unlock()>
// writer
mutex.lock()
// work the database
mutex.unlock()
- use a mutex semaphore to implment atomicity
- it allows as many readers as possible
- starves writers
- a split-binary solution
- what do you want to do
- no writers in and readers waiting - let a reader go
- nothing in and writers waiting - let a writer go
- nothing in and nothing waiting - nothing
int nr = 0
int nw = 0
int dr = 0
int dw = 0
semaphore mutex(1)
semaphore waitingr(0)
semaphore waitingw(0)
// reader
mutex.lock()
if (nw > 0)
dr++
mutex.unlock()
waitingr.wait()
nr++
pass()
// work the database
mutex.lock()
nr--
pass()
// writer
mutex.lock()
if nr > 0 or nw > 0
dw++
mutex.unlock()
waitingw.wait()
nw++
pass()
//work the database
mutex.lock()
nw--
pass()
// pass
if (nw == 0 and dr > 0)
dr--
waitingr.signal()
else if (nr == 0 and nw == 0 and dw > 0)
dw--
waitingw.signal()
else
mutex.unlock()
This page last modified on 2 July 2002.