<< Chapter < Page | Chapter >> Page > |
Both of the shortcomings can be overcome by not restricting ourselves to a binary variable, but instead define a generalized or counting semaphore.
where finding S>0 and decrementing S is atomic
These counting semaphores can solve what I call the semi-critical-section problem, where you premit up to k processes in thesection. When k=1 we have the original critical-section problem.
initially S=k
loop forever
P(S)
SCS<== semi-critical-section
V(S)
NCS
Producer-consumer problem
Initially e=k, f=0 (counting semaphore); b=open (binary semaphore)
Producer Consumer
loop forever loop forever
produce-item P(f)
P(e) P(b); take item from buf; V(b)
P(b); add item to buf; V(b) V(e)
V(f) consume-item
Unfortunately, it is rare to find hardware that implements P&V directly (or messages, or monitors). They all involve some sort of scheduling and it is not clear that scheduling stuff belongs in hardware(layering). Thus semaphores must be built up in software using some lower-level synchronization primitive provided by hardware.
Need a simple way of doing mutual exclusion in order to implement P's and V's. We could use atomic reads and writes, as in "too muchmilk" problem, but these are very clumsy.
Uniprocessor solution: Disable interrupts.
class semaphore {
private int count;public semaphore (int init)
{count = init;
}public void P ()
{while (1) {
Disable interrupts;if (count>0) {
count--;Enable interrupts;
} else {Enable interrupts;
}}
}public void V ()
{Disable interrupts;
count++;Enable interrupts;
}}
Notification Switch
Would you like to follow the 'Operating systems' conversation and receive update notifications?