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 or m == 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 and s)

  • 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/