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