Producer and Consumer Problem
This is one of the most common problems in Concurrency. We studied this in SE350.
Problem setup:
- One or more producers are generating data and placing these in a bufferer
- A single consumer is taking items out of the buffer one at time
- Only one producer or consumer may access the buffer at any one time
Producer
while (true) {
/* Produce item v */
b[in] = v;
in++;
}
Consumer
while (true) {
while (in < out) /* Do nothing */;
w = b[out];
out++;
/* Consume item w */
}
wait()
: Decreases the semaphore’s value by 1 if it’s greater than zero, blocking otherwise until it becomes positive.signal()
: Increases the semaphore’s value by 1, potentially unblocking a waiting process.
Ways to solve:
A solution using Binary Semaphores:
/* program producerconsumer */
int n;
binary_semaphore s = 1, delay = 0;
void producer() {
while (true) {
produce();
semWaitB(s);
append();
n++;
if (n==1) semSignalB(delay);
semSignalB(s);
}
}
void consumer() {
int m; /* a local variable */
semWaitB(delay);
while (true) {
semWaitB(s);
take();
n--;
m = n;
semSignalB(s);
consume();
if (m==0) semWaitB(delay);
}
}
void main() {
n = 0;
parbegin (producer, consumer);
}
- I’m confused why you need to check
n == 1
orm == 0
?
Naa, binary semaphores are confusing
/* program producerconsumer */
semaphore n = 0, s = 1;
void producer() {
while (true) {
produce();
semWait(s);
append();
semSignal(s);
semSignal(n);
}
}
void consumer() {
while (true) {
semWait(n);
semWait(s);
take();
semSignal(s);
consume();
}
}
void main() {
parbegin (producer, consumer);
}
Why are there 2 different semaphore signals?? (
n
ands
)
s
is to ensure Mutual Exclusion and makes sense to me (initially 1)n
is the ensure synchronization, specifically the number of items available (initially 0)Consider the scenario where the consumer runs faster than the producer. If you don’t have the
n
semaphore, then you might end up with the consumer consuming more than what the queue actually has.
Bounded Buffer
/* program boundedbuffer */
const int sizeofbuffer = /* buffer size */;
semaphore s = 1, n = 0, e = sizeofbuffer;
void producer() {
while (true) {
produce();
semWait(e);
semWait(s);
append();
semSignal(s);
semSignal(n);
}
}
void consumer() {
while (true) {
semWait(n);
semWait(s);
take();
semSignal(s);
semSignal(e);
consume();
}
}
void main() {
parbegin (producer, consumer);
}
C++
How to solve? Use the condition_variable.
https://www.geeksforgeeks.org/producer-consumer-problem-using-semaphores-set-1/