CS 3733 Operating Systems
Lecture 32 [4/3/98]: Semaphores
Read Sections 8.2 of PUP and 6.4 of SG
- Semaphore: an integer variable
P
which can only be accessed through
two atomic operations: wait (P)
and
signal (V)
.
(Note: Tanenbaum calls these DOWN
and UP
.)
-
An atomic operation is one that can't be interrupted so once a process
starts the operation, it is guaranteed that no one will mess it up.
(The notion of can't be
interrupted is subtle.)
- Pseudo-code for busy-waiting version of semaphores:
wait(int *SP): signal(int *SP):
while (*SP <= 0) ; *SP = *SP + 1;
*SP = *SP - 1;
Remember: these are atomic.
- Example 1:
int S;
while (1) {
wait(&S);
critical section
signal(&S);
}
- How should S be initialized?
- What if it is initialized to 0? --- No one gets in.
- What if it is initialized to 1?
- What if it is initialized to 10?
- Example 2:
Suppose we have two concurrent processes and process 1 must execute
S1
before process 2 executes S_2
.
Process 1 executes:
S1;
signal(&sync);
Process 2 executes:
wait(&sync);
S2;
How should sync
be initialized?
- Example 3: When a process uses more than
one semaphore, a deadlock can occur.
That is, the process will never return from the wait.
Consider two processes P1 and P2 executing the following code:
P_1 code:
wait(&S);
...
signal(&Q);
P_2 code:
wait(&Q);
...
signal(&S);
S
and Q
are initialized
to 0.
- Implementation of busy-waiting semaphore using test-and-set
(Example 8.11 and Exercise 8.11 of PUP)
- Pseudo-code for non-busy waiting version of semaphores
(Example 8.12 of PUP)
Skill: Understand semaphores.
Revised 3/31/98