The idea:
S.value--;
if (S.value < 0) {
<Add this process to S.list>
<block>
}
signal(S):
S.value++;
if (S.value <= 0) {
<move a process from S.list to the ready list>
}
Standard ways to use a semaphore:
Protect a critical section:
S is initialized to 1:
wait(S);
<C.S.>
signal(S);
Make sure P1 executes before P2:<do something> signal(S);P2
wait(S); <do something>
Note: the type of queue we use will determine the order in which processes
which are waiting for a given semaphore get serviced.
A FIFO queue guarantees bounded waiting, but othe queue techniques may produce
starvation.
Care must be taken when dealing with semaphores:
Consider two processes P1 and P2.
P1 executes:
wait(S);
...
signal(Q);
while P2 executes:
wait(Q);
...
signal(S);
Each is waiting for the other and if the semaphores are both initialized to
0, a deadlock can occur.
Bounded buffer problem using sempahores
Assume we have n buffers.
Use three semaphores:
produce item in nextp
wait(empty)
wait(mutex)
<add nextp to buffer>
signal(mutex)
signal(full)
Consumer Loop
wait(full)
wait(mutex)
<remove item from buffer, put in nextp>
signal(mutex)
signal(empty)
consume item in nextp