guys. I am learning about the Producer-Consumer Problem. My professor gave us an example code using a classical int array
to share resources between the two threads. It works as expected, however, I wanted to try it using std:list
class from C++ and it doesn't work as expected. The consumer seems not to respect sem_wait(&full);
so it tries to consume many times when there is nothing in the shared list.
Original code with array buffer
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define N 2
#define TRUE 1
int buffer[N], in = 0, out = 0;
sem_t empty, full, mutexC, mutexP;
void *producer(void *arg) {
while(TRUE) {
sleep(rand()%5);
sem_wait(&empty);
sem_wait(&mutexP);
buffer[in] = rand() % 100;
printf("Producing buffer[%d] = %d\n", in, buffer[in]);
in= (in+1) % N;
sem_post(&mutexP);
sem_post(&full);
}
}
void *consumer(void *arg) {
while(TRUE) {
sleep(rand()%5);
sem_wait(&full);
sem_wait(&mutexC);
printf("Consuming buffer[%d] = %d\n", out, buffer[out]);
out = (out+1) % N;
sem_post(&mutexC);
sem_post(&empty);
}
}
int main(int argc, char *argv[ ]) {
pthread_t cons, prod;
sem_init(&mutexC, 0, 1);
sem_init(&mutexP, 0, 1);
sem_init(&empty, 0, N);
sem_init(&full, 0, 0);
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_exit(0);
}
My implementation with list:
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <list>
#define TRUE 1
#define N 2
using namespace std;
list<int> sharedList;
sem_t empty, full, mutexC, mutexP;
void *producer(void *arg) {
while(TRUE) {
sleep(rand()%5);
sem_wait(&empty);
sem_wait(&mutexP);
int prod = rand() % 100;
cout << "producing: " << prod << endl;
sharedList.push_back(prod);
sem_post(&mutexP);
sem_post(&full);
}
}
void *consumer(void *arg) {
while(TRUE) {
sleep(rand()%5);
sem_wait(&full);
sem_wait(&mutexC);
if (!sharedList.empty()) {
cout << "consuming: ";
cout << sharedList.front() << endl;
sharedList.pop_front();
} else {
cout << "not possible to consume" << endl;
}
sem_post(&mutexC);
sem_post(&empty);
}
}
int main(int argc, char *argv[ ]) {
pthread_t cons, prod;
sem_init(&mutexC, 0, 1);
sem_init(&mutexP, 0, 1);
sem_init(&empty, 0, N);
sem_init(&full, 0, 0);
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_exit(0);
}
The - unexpected - logs from my implementation:
producing: 73
consuming: 73
not possible to consume
producing: 44
consuming: 44
producing: 9
producing: 65
consuming: 9
producing: 87
consuming: 65
consuming: producing: 29
87
not possible to consume
consuming: 29
producing: 9
producing: 60
consuming: 9
producing: 78
Can somebody explain to me what is happening? Thanks in advance!