#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#define NUM_PROD 4
#define NUM_CONS 4
#define STORAGE_SPACE 3
int buffer[STORAGE_SPACE];
int last;
pthread_mutex_t mutex;
pthread_cond_t can_produce;
pthread_cond_t can_consume;
void printBuffer()
{
int i = 0;
for (i = 0; i < STORAGE_SPACE; i++)
{
printf("%d\n", buffer[i]);
}
}
typedef struct Monitor {
//shared variable/resources
pthread_mutex_t mutex;
pthread_cond_t can_produce;
pthread_cond_t can_consume;
int buffer[STORAGE_SPACE];
int last;
}Monitor;
void initMonitor(Monitor* monitor){
//init shared variable & synchr objects
monitor->last = 0;
pthread_mutex_init(&monitor->mutex, NULL);
pthread_cond_init(&monitor->can_produce, NULL);
pthread_cond_init(&monitor->can_consume, NULL);
}
void *produce(Monitor* monitor, void *threadid){
//access and manipulate shared variable/res
long tid;
tid = (long)threadid;
int i, item;
srand(time(NULL));
for( i = 0; i < 5; i ++){
pthread_mutex_lock(&monitor->mutex);
while(last == STORAGE_SPACE){
pthread_cond_wait(&monitor->can_produce, &monitor->mutex);
}
item = rand() % 50;
buffer[last] = item;
printf("prod %ld inserts item %d\n", tid, buffer[last]);
last++;
printBuffer();
pthread_cond_signal(&monitor->can_consume);
pthread_mutex_unlock(&monitor->mutex);
}
pthread_exit(NULL);
}
void *consume(Monitor* monitor, void *threadid){
long tid;
tid = (long)threadid;
int taken;
while(1){
pthread_mutex_lock(&monitor->mutex);
while(monitor->last == 0){
pthread_cond_wait(&monitor->can_consume, &monitor->mutex);
}
taken = buffer[last - 1];
buffer[last - 1] = 0;
printf("consumer %ld took %d \n", tid, taken);
last--;
printBuffer();
pthread_cond_signal(&monitor->can_produce);
pthread_mutex_unlock(&monitor->mutex);
}
pthread_exit(NULL);
return NULL;
}
int main(int argc, char *argv[])
{
//init
Monitor monitor;
initMonitor(&monitor);
pthread_t prod[NUM_PROD], cons[NUM_CONS];
int rc;
long t;
//init mutex & cond
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&can_produce, NULL);
pthread_cond_init(&can_consume, NULL);
//creating threads
for (t = 0; t < NUM_PROD; t++)
{
rc = pthread_create(&prod[t], NULL, produce, (void *)&monitor);
if (rc)
{
exit(-1);
}
}
for (t = 0; t < NUM_CONS; t++)
{
rc = pthread_create(&cons[t], NULL, consume, (void *)&monitor);
if (rc)
{
exit(-1);
}
}
//joining threads
for (t = 0; t < NUM_PROD; t++)
{
pthread_join(prod[t], NULL);
}
for (t = 0; t < NUM_CONS; t++)
{
pthread_join(cons[t], NULL);
}
//destroy mutex and condition variables
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&can_produce);
pthread_cond_destroy(&can_consume);
pthread_exit(NULL);
return 0;
}
Hey guys,
I would like to implement a monitor in this implementation of the producer/consumer problem.
I implemented the monitor struct as i think is correct (?) however, there is a problem when passing the functions to pthread_create and as a result I am only getting prod 0 thread being active.
I'm also not sure why the consumer function isn't being executed, but my guess is that both have to do with the fact that the produce / consume functions have (monitor, threadid) as arguments, which doesn't work with the parameters of the 3rd argument in pthread_create().
After hours of trying to google and such - I hope some one can explain where my fault(s) are.
Thanks!