2. prodConM
This is a second version of the program. In this version, there are 3 producers and 2 consumers. The producers have to compete with each other, as well as with consumers. When two or more producers are waiting to dump their produce into the buffer, the products must be inserted into the main buffer in ascending order.
//use this code at your own risk
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <semaphore.h>
typedef int buffer_item;
#define BUFFER_SIZE 5
typedef struct
{
buffer_item buffer[BUFFER_SIZE];
buffer_item waiting_items[BUFFER_SIZE];
int num_of_waiting_items;
int full;
int empty;
int buffer_pos;
int waiting_pos;
pthread_mutex_t *mutex;
sem_t *priority;
}queue;
int producer_sleep_time_max;
int consumer_sleep_time_max;
int TRUE = 1;
void *producer(void *param)
{
queue *buff = (queue*)param;
buffer_item item;
while(TRUE)
{
srand(time(NULL));
int random_sleep_time = getRandom(0, producer_sleep_time_max);
sleep(random_sleep_time);
item = getRandom(0,1000);
//wait on priority
sem_wait(buff->priority);
if(buff->num_of_waiting_items < BUFFER_SIZE)
{
buff->waiting_pos++;
buff->waiting_items[buff->waiting_pos] = item;
buff->num_of_waiting_items++;
//sort the waiting items
int i = buff->waiting_pos;
for(i; i > 0; i–)
{
buffer_item smallest_item = buff->waiting_items[i];
int j = i-1;
for(j; j == 0;j–)
{
if(smallest_item > buff->waiting_items[j])
{
buffer_item temp_item = smallest_item;
smallest_item = buff->waiting_items[j];
buff->waiting_items[j] = temp_item;
}
}
buff->waiting_items[i] = smallest_item;
}
}
if(buff->full < BUFFER_SIZE)
{
//acquire mutex lock now
pthread_mutex_lock(buff->mutex);
//process waiting items;
item = buff->waiting_items[buff->waiting_pos];
if(insert_item(item,buff) == -1)
{
printf(“nProduction failed”);
} else
{
printf(“nProducer produced:%d”,item);
//move down to the next item;
buff->waiting_pos–;
buff->num_of_waiting_items–;
//print buffer content
printf(“nBuffer content:”);
int m=0;
for(m;m < BUFFER_SIZE;m++)
{
printf(“%d”,buff->buffer[m]);
printf(“t”);
}
}
//release the mutex
pthread_mutex_unlock(buff->mutex);
}
//Inrement priority
sem_post(buff->priority);
}
}
void *consumer(void *param)
{
buffer_item item;
queue *con =(queue*)param;
while(TRUE)
{
srand(time(NULL));
int random_sleep_time = getRandom(0, consumer_sleep_time_max);
sleep(random_sleep_time);
//acquire mutex lock
pthread_mutex_lock(con->mutex);
if(remove_item(&item,con) == -1)
{
printf(“nConsumer could not consume”);
}else
{
printf(“nConsumer consumed:%d”,item);
//print buffer content
printf(“nBuffer content:”);
int i = 0;
for(i; i < BUFFER_SIZE;i++)
{
printf(“%d”,con->buffer[i]);
printf(“t”);
}
}
//Release mutex
pthread_mutex_unlock(con->mutex);
}
}
int getRandom(int min, int max)
{
return ( rand()% ((max-min)+1));
}
int insert_item(buffer_item item,void *param)
{
queue *in = (queue*)param;
if(in->empty > 0 && in->full < BUFFER_SIZE)
{
in->buffer_pos++;
in->buffer[in->buffer_pos] = item;
in->empty–;
in->full++;
return 0;
}else
return -1;
}
int remove_item(buffer_item *item,void *param)
{
queue *out = (queue*)param;
if(out->full > 0)
{
*item = out->buffer[out->buffer_pos];
out->buffer[out->buffer_pos] = -1;
out->empty++;
out->full–;
out->buffer_pos–;
return 0;
}else
return -1;
}
int main(int argc, char *argv[])
{
int main_sleep_time;
// if user didn’t enter how long to sleep, number of producer and consumer, error
if(argc != 4)
{
printf(“Program requires 3 integer arguments”);
return -1;
}else if( atoi(argv[2]) < 0 || atoi(argv[3]) < 0 || atoi(argv[1]) < 0)
{
printf(“Program requires 3 positive integers for: Main sleep time, Producer sleep time and Consumer sleep time”);
return -1;
}else
{
//Get the main sleep time, producer sleep time max and consumer sleep time max
main_sleep_time = atoi(argv[1]);
producer_sleep_time_max = atoi(argv[2]);
consumer_sleep_time_max = atoi(argv[3]);
}
queue *buff;
buff->full = 0;
buff->empty = BUFFER_SIZE;
buff->num_of_waiting_items = 0;
buff->waiting_pos = -1;
buff->buffer_pos = -1;
//initialize arrays to negatives
buff->buffer[0] = -1;
buff->buffer[1] = -1;
buff->buffer[2] = -1;
buff->buffer[3] = -1;
buff->buffer[4] = -1;
buff->waiting_items[0] = -1;
buff->waiting_items[1] = -1;
buff->waiting_items[2] = -1;
buff->waiting_items[3] = -1;
buff->waiting_items[4] = -1;
//declare thread identifiers
pthread_t p1;
pthread_t p2;
pthread_t p3;
pthread_t c1;
pthread_t c2;
//Initialize the mutex
pthread_mutex_init(buff->mutex,NULL);
//Initialize priority
sem_init(buff->priority,0,1);
//create 3 producers
pthread_create(&p1,NULL,producer,buff);
pthread_create(&p2,NULL,producer,buff);
pthread_create(&p3,NULL,producer,buff);
//create 2 consumers
pthread_create(&c1,NULL,consumer,buff);
pthread_create(&c2,NULL,consumer,buff);
// Send main thread to sleep
sleep(main_sleep_time);
exit(0);
}
Its such as you learn my mind! You appear to understand so much about this, like you wrote the e-book in it or something. I feel that you can do with some p.c. to drive the message home a little bit, but instead of that, that is magnificent blog. An excellent read. I will definitely be back.