Semaphore
Semaphore
q A semaphore is an object that consists of a counter, a waiting list of processes and two methods (e.g., functions): signal and wait.
method signal counter method wait waiting list
semaphore
q After decreasing the counter by 1, if the counter value becomes negative, then vadd the caller to the waiting list, and then vblock itself.
q After increasing the counter by 1, if the new counter value is not positive, then vremove a process P from the waiting list, vresume the execution of process P, and return
3
q If S.count < 0, abs(S.count) is the number of waiting processes. q This is because processes are added to (resp., removed from) the waiting list only if the counter value is < 0 (resp., <= 0).
4
q The waiting list can be implemented with a queue if FIFO order is desired. q However, the correctness of a program should not depend on a particular implementation of the waiting list. q Your program should not make any assumption 5 about the ordering of the waiting list.
q The caller may be blocked in the call to wait(). q The caller never blocks in the call to signal(). If S.count > 0, signal() returns and the caller continues. Otherwise, a waiting process is released and the caller continues. In this case, two processes continue.
6
q wait() and signal() must be executed atomically (i.e., as one uninterruptible unit). q Otherwise, race conditions may occur. q Homework: use execution sequences to show race conditions if wait() and/or signal() is not executed atomically.
7
q After three processes pass through wait(), this section is locked until a process calls signal().
10
Use 3: Notification
semaphore S1 = 1, S2 = 0; process 1 process 2 while (1) { while (1) { // do something // do something notify S1.wait(); S2.wait(); cout << 1; cout << 2; S2.signal(); notify S1.signal(); // do something // do something } }
q Process 1 uses S2.signal() to notify process 2, indicating I am done. Please go ahead. q The output is 1 2 1 2 1 2 q What if both S1 and S2 are both 0s or both 1s? 11 q What if S1 = 0 and S2 = 1?
Five philosophers are in a thinking - eating cycle. When a philosopher gets hungry, he sits down, picks up two nearest chopsticks, and eats. A philosopher can eat only if he has both chopsticks. After eating, he puts down both chopsticks and thinks. This cycle continues.
12
philosopher i wait for my left chop while (1) { // thinking wait for my right chop C[i].wait(); C[(i+1)%5].wait(); release my right chop // eating C[(i+1)%5].signal(); C[i].signal(); release my left chop // finishes eating }
while (1) { while (1) { // thinking // thinking C[i].wait(); C[(i+1)%5].wait(); C[(i+1)%5].wait(); C[i].wait(); // eating // eating C[(i+1)%5].signal(); C[i].signal(); C[i].signal(); C[(i+1)%5].signal(); // finishes eating; // finishes eating } } lock left chop lock right chop
16
bounded-buffer
Problem Analysis
q A producer deposits info into Buf[in] and a consumer retrieves info from Buf[out]. q in and out must be advanced. q in is shared among producers. q out is shared among consumers. q If Buf is full, producers should be blocked. buffer is implemented with an array Buf[ ] q If Buf is empty, consumers should be blocked.
21
q We need a sem. to protect the buffer. q A second sem. to block producers if the buffer is full. q A third sem. to block consumers if the buffer is empty.
22
Solution
no. of slots semaphore NotFull=n, NotEmpty=0, Mutex=1;
producer
consumer
while (1) { while (1) { NotFull.wait(); NotEmpty.wait(); Mutex.wait(); Mutex.wait(); Buf[in] = x; x = Buf[out]; in = (in+1)%n; out = (out+1)%n; Mutex.signal(); Mutex.signal(); NotEmpty.signal(); NotFull.signal(); } } notifications critical section
23
Question
q What if the producer code is modified as follows? q Answer: a deadlock may occur. Why?
while (1) { Mutex.wait(); NotFull.wait(); Buf[in] = x; order changed in = (in+1)%n; NotEmpty.signal(); Mutex.signal(); }
24
Problem Analysis
q We need a semaphore to block readers if a writer is writing. q When a writer arrives, it must be able to know if there are readers reading. So, a reader count is required which must be protected by a lock. q This reader-priority version has a problem: bounded waiting condition may be violated if readers keep coming, causing the waiting writers no chance to write.
26
q When a reader comes in, it increase the count. q If it is the 1st reader, waits until no writer is writing, q Reads data. q Decreases the counter. q Notifies the writer that no reader is reading if it is the last.
27
q When a writer comes in, it waits until no reader is reading and no writer is writing. q Then, it writes data. q Finally, notifies readers and writers that no writer is in.
28
Solution
semaphore Mutex = 1, WrtMutex = 1; int RdrCount;
reader
writer
while (1) { while (1) { Mutex.wait(); RdrCount++; if (RdrCount == 1) blocks both readers and writers WrtMutex.wait(); WrtMutex.wait(); Mutex.signal(); // read data // write data Mutex.wait(); RdrCount--; if (RdrCount == 0) WrtMutex.signal(); WrtMutex.signal(); Mutex.signal(); } } 29