Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Q1 (80): Please implement the producer consumer problem with a slight variation.

ID: 3762496 • Letter: Q

Question

Q1 (80): Please implement the producer consumer problem with a slight variation. In C Program Language

In this case, we have one producer thread which can produce any random number in the buffer. But there should be two consumer threads. One consumer thread will consume only odd values while the second consumer thread will consume only even values from the buffer.

Both consumer threads and the producer thread should be running concurrently. The consumer threads should wait (in a while loop) if there is nothing to be consumed for them. The producer thread should wait (in a while loop) if the buffer is full.

You can include some sleep statements in your program to make the producer and consumers to sleep for a while to see your program in action in slow motion. Your program should handle all synchronization issues.

Please explain which part of your program is critical section and why? Please explain with an example scenario on what can go wrong if you do not use proper synchronization tool to protect the critical section?

Explanation / Answer

Answer :

The Critical Section of the program is presented in bold and in our program if we do not use proper synchronization methods are followed then there might be chance that the scenario may be in which there exists two Destinct processes both operating on a single shared data area. One process, the Producer inserts information into the data area whilst the other process, the Consumer, removes information from that same area. In order for the Producer to insert information into the data area, there must be enough space. The Producer's sole function is to insert data into the data-area, it is not allowed to remove any data from the area. Similarly, for the Consumer to be able to remove information from the data area, there must be information there in the first place. Once again, the sole function of the Consumer is to remove data from the data area. If no data is present then the Consumer is not allowed to insert some data of it's own to later be removed by itself.In other words,the Producer relies on the Consumer to make space in the data-area so that it may insert more information whilst at the same time, the Consumer relies on the Producer to insert information into the data area so that it may remove that information. It therefore follows that a mechanism is required to allow the Producer and Consumer to communicate so that they know when it is safe to attempt to write or read information from the data-area in our program.Therefore, the solution of the Producer-Consumer problem lies with plan a suitable communication protocol through which the two processes may exchange information

Program :

#include <stdlib.h>

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include "buffer.h"

#define RAND_DIVISOR 100000000
#define TRUE 1

/* The mutex lock */
pthread_mutex_t mutex;

/* the semaphores */
sem_t full, empty;

/* the buffer */
buffer_item buffer[BUFFER_SIZE];

/* buffer counter */
int counter;

pthread_t tid; //Thread ID
pthread_attr_t attr; //Set of thread attributes

void *producer(void *param); /* the producer thread */
void *consumer(void *param); /* the consumer thread */

void initializeData() {

/* Create the mutex lock */
pthread_mutex_init(&mutex, NULL);

/* Create the full semaphore and initialize to 0 */
sem_init(&full, 0, 0);

/* Create the empty semaphore and initialize to BUFFER_SIZE */
sem_init(&empty, 0, BUFFER_SIZE);

/* Get the default attributes */
pthread_attr_init(&attr);

/* init buffer */
counter = 0;
}

/* Producer Thread */
void *producer(void *param) {
buffer_item item;

while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);

/* generate a random number */
item = rand();

/* acquire the empty lock */
sem_wait(&empty);
/* acquire the mutex lock */
pthread_mutex_lock(&mutex);

if(insert_item(item)) {
fprintf(stderr, " Producer report error condition ");
}
else {
printf("producer produced %d ", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal full */
sem_post(&full);
}
}

/* Consumer Thread */
void *consumer(void *param) {
buffer_item item;

while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);

/* aquire the full lock */
sem_wait(&full);
/* aquire the mutex lock */
pthread_mutex_lock(&mutex);
if(remove_item(&item)) {
fprintf(stderr, "Consumer report error condition ");
}
else {
printf("consumer consumed %d ", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal empty */
sem_post(&empty);
}
}

/* Add an item to the buffer */
int insert_item(buffer_item item) {
/* When the buffer is not full add the item
and increment the counter*/
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
}
else { /* Error the buffer is full */
return -1;
}
}

/* Remove an item from the buffer */
int remove_item(buffer_item *item) {
/* When the buffer is not empty remove the item
and decrement the counter */
if(counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
}
else { /* Error buffer empty */
return -1;
}
}

int main(int argc, char *argv[]) {
/* Loop counter */
int i;

/* Verify the correct number of arguments were passed in */
if(argc != 4) {
fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT> ");
}

int mainSleepTime = atoi(argv[1]); /* Time in seconds for main to sleep */
int numProd = atoi(argv[2]); /* Number of producer threads */
int numCons = atoi(argv[3]); /* Number of consumer threads */

/* Initialize the app */
initializeData();

/* Create the producer threads */
for(i = 0; i < numProd; i++) {
/* Create the thread */
pthread_create(&tid,&attr,producer,NULL);
}

/* Create the consumer threads */
for(i = 0; i < numCons; i++) {
/* Create the thread */
pthread_create(&tid,&attr,consumer,NULL);
}

/* Sleep for the specified amount of time in milliseconds */
sleep(mainSleepTime);

/* Exit the program */
printf("Exit the program ");
exit(0);
}