Solve the Consumer/Producer problem using semaphores. A skeleton program (Save i
ID: 3604055 • Letter: S
Question
Solve the Consumer/Producer problem using semaphores. A skeleton program (Save it as producer_consumer.c) is provided to you: The main function creates 2 threads: consumer represents the consumer and executes the consume function, and producer represents the producer and executes the produce function. You should declare and initialize 3 semaphores. Those semaphores should be used in the consume(..) and produce(...) functions.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h> //compile and link with -pthread
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int in, out;
int num;
void *produce( void *ptr ) {
int item;
while(1){
usleep(rand() % 1000); //sleep
printf("Producer wants to produce. ");
//critical section below
item = rand() % 10;
num++;
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
//critical section above
printf("Producer entered %d. Buffer Size = %d ", item, num);
}
}
void *consume( void *ptr ) {
int item;
while(1){
usleep(rand() % 1000); //sleep
printf("Consumer wants to consume. ");
//critical section below
num--;
int item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
//critical section above
printf("Consumer consumed %d. Buffer Size = %d ", item, num);
}
}
int main() {
pthread_t consumer, producer;
out = 0; //index of the item to be consumed next
in = 0; //index of the item to be produced next
num = 0; //number of items in the buffer
srand(time(NULL));
pthread_create( &consumer, NULL, consume, NULL);
pthread_create( &producer, NULL, produce, NULL);
pthread_join( producer, NULL);
pthread_join( consumer, NULL);
pthread_exit(NULL);
}
Explanation / Answer
Below is the modified code using 3 semaphores mutex, full_sem, empty_sem out of which mutex is binary semaphore initialized to 1 and remaining two are counting semaphore. Semaphore full_sem keep counting the number of items present in buffer, so it need to have positive value in order to make consumer process to consume item and after consumtion it increment empty_sem by one which is a counting semaphore to keep track of empty buffers. Producer process need empty_sem to have non zero value in order to keep some item in buffer and then increment full_sem by one.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h> //compile and link with -pthread
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int in, out;
int num;
sem_t mutex; /*we will use it as binary semaphore to ensure only one of producer or consumer process enters critical section
sem_t full_sem; /* we will use it as counting semaphone when 0, buffer is empty */
sem_t empty_sem; /* we will use it as counting semaphone, when 0, buffer is full, i.e. no empty space remain. */
void *produce( void *ptr ) {
int item;
while(1){
usleep(rand() % 1000); //sleep
printf("Producer wants to produce. ");
sem_wait(&empty_sem); //to check whether some buffer space is empty, then decrement empty space by 1
sem_wait(&mutex); //if mutex is 1 then makes it 0 and the process enter critical section
//critical section below
item = rand() % 10;
num++;
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
//critical section above
sem_post(&mutex); //again makes mutex to 1
sem_post(&full_sem); //increment the full_sem by 1
printf("Producer entered %d. Buffer Size = %d ", item, num);
}
}
void *consume( void *ptr ) {
int item;
while(1){
usleep(rand() % 1000); //sleep
printf("Consumer wants to consume. ");
sem_wait(&full_sem); //to check whether some buffer space contains item, then decrement it by 1
sem_wait(&mutex); //if mutex is 1 then makes it 0 and the process enter critical section
//critical section below
num--;
int item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
//critical section above
sem_post(&mutex); //again makes mutex to 1
sem_post(&empty_sem); //increment the empty_sem by 1 which means one buffer space is empty
printf("Consumer consumed %d. Buffer Size = %d ", item, num);
}
}
int main() {
pthread_t consumer, producer;
out = 0; //index of the item to be consumed next
in = 0; //index of the item to be produced next
num = 0; //number of items in the buffer
sem_init(&mutex, 0, 1); //initailizing mutex to 1, 2nd parameter 0 means mutex can be shared only between threads of same process
sem_init(&full_sem, 0, 0); //initailizing full_sem to 0 because initially no items in buffer
sem_init(&empty_sem, 0, BUFFER_SIZE); //initailizing empty_sem to BUFFER_SIZE since initially all the buffer are empty
srand(time(NULL));
pthread_create( &consumer, NULL, consume, NULL);
pthread_create( &producer, NULL, produce, NULL);
pthread_join( producer, NULL);
pthread_join( consumer, NULL);
pthread_exit(NULL);
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.