Binary Semaphore: S1_a, S1_b, S2_a, S2_b, S3, S4_a, S4_b, S4_c, S5, S6, S7, S8
P1: P1 operations;
S1_a.V();
S1_b.V();
P2: P2 operations;
S2_a.V();
S2_b.V();
P3: S1_a.P();
S2_a.P();
P3 operations;
S3.V();
P4: S1_b.P();
S2_b.P();
P4 operations;
S4_a.V();
S4_b.V();
S4_c.V();
P5: S4_a.P();
P5 operations;
S5.V();
P6: S4_b.P();
P6 operations;
S6.V();
P7: S4_c.P();
P7 operations;
S7.V();
P8: S3.P();
S5.P();
P8 operations;
S8.V();
P9: S6.P();
S7.P();
S8.P();
P9 operations;
#2
Producer
//Produce item
P(mutex);
P(empty);
//CS
V(mutex);
V(full);
Consumer
P(mutex);
P(full);
//CS
V(mutex);
V(empty);
//Consume item
As can be seen above, with the exchange of wait(empty) and wait(mutex) in the producer and wait(full) and wait(mutex) in the consumer, deadlock can easily occur in the following two situations:
(1) When full = n and empty = 0 and producer reaches mutex first, it will wait for consumer to consume one or more items, which will not happen because consumer is blocked out of mutex.#3
(2) When full = 0 and empty = n and consumer reaches mutex first, it will wait for producer to produce one or more items, which again will not happen because producer is blocked out of mutex.
Bounded_Semaphore: Monitor
var s: integer;
var c1, c2: condition;
procedure P()
begin
if (s <= 0) c1.wait();
s--;
c2.signal();
end
procedure V()
begin
if (s >= smax) c2.wait();
s++;
c1.signal();
end
//Initialization code
begin
s = smax;
end