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);

}

1 thought on “3 Producers and 2 Consumers Problem using PThread in C Language on Linux System

  1. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Name *