I'm solving a producer / consumer problem using two threads. I think I've done something wrong because it seems to give the same serial output every time. What's the problem?
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <stdbool.h>
sem_t empty, full, mutex;
int bound[5];
int a,b;
void *producer(void *arg) {
for (int i = 0; i < 15; i++) {
sem_wait(&empty);
sem_wait(&mutex);
printf("%d is produced\n", i);
sleep(1);
bound[(++a) % 5] = i;
sem_post(&mutex);
sem_post(&full);
}
}
void *consumer(void *arg) {
int consumed;
for (int i = 0; i < 15; i++) {
sem_wait(&full);
sem_wait(&mutex);
consumed = bound[(++b) % 5];
printf("%d is consumed\n",consumed);
sleep(1);
sem_post(&mutex);
sem_post(&empty);
}
}
void main() {
pthread_t prod, con;
sem_init(&mutex, 0, 1);
sem_init(&full, 0, 0);
sem_init(&empty, 0, 5);
pthread_create(&prod,NULL,producer,NULL);
pthread_create(&con,NULL,consumer,NULL);
pthread_join(prod,NULL);
pthread_join(con,NULL);
}
Output is like producer first consumes 5 times, then the consumer consumes them all, then producer produces again and repeat:
0 is produced 1 is produced 2 is produced 3 is produced 4 is produced 0 is consumed 1 is consumed 2 is consumed 3 is consumed 4 is consumed 5 is produced
and so on.
Just because one thread posts a semaphore another thread is waiting for there is no guarantee that the other thread gets to run immediately. If the first thread is very fast it may regain the semaphore before the other thread gets to run. This could be the reason you see alternating series of 5 produced and 5 consumed.
Try making buf
larger (e.g. 1000) and do 1500 loops in both producer and consumer (also change the sem_init
). Then you may see another pattern.
BTW: Remove the two sleep calls. They are done while you are holding mutex
so the other thread can't run anyway.