// Producer process i // Consumer Process j Object x = null; Object y = null; while(true) { while(true) { // produce data x ... P(full); P(mutexC); P(empty); y = buf[out]; P(mutexP); out = (out + 1) % n; buf[in] = x; V(mutexC); in = (in + 1) % n; V(empty) V(mutexP); // use the data y ... V(full); } } // Shared variables integer n = BUFFER_SIZE, in = 0, out =0; Object[] buf = new Object[n]; general semaphore empty = n, full = 0; binary semaphore mutexP = 1, mutexC = 1;
In this case the problem is to ensure that two different producers don't attempt to append items to the buffer at the same time, as this can result in both items being put in the same slot. This can happen if both assign to buf[in] before either increments in (see Lecture 2). Similarly, we must ensure that two different consumers don't attempt to remove the same item, if both copy the same item into y before either increments out. Both appending and removing items become critical sections. Both operations must be executed with mutual exclusion with respect to other producers (for append) and consumers (for remove), but one producer and one consumer can execute concurrently with one another, since the empty and full semaphores already ensure that the producer and consumer can't access the same slot. The solution is similar to the semaphore solution to the single Producer-single Consumer problem using a bounded buffer presented in lecture 8, with additional binary semaphores to protect each critical section (see Lecture 7).