Fill in the skeleton code that is provided below: Producer/Consumer Problem -Mul
ID: 3826247 • Letter: F
Question
Fill in the skeleton code that is provided below:
Producer/Consumer Problem
-Multiple producers fill data in a buffer
– Multiple consumers remove data from the same buffer
– Producers need to wait if buffer is full
– Consumers need to wait if buffer if empty
– At any time, only one producer or consumer can operate the buffer
Program two solutions to solve the problem
– Use Locks and Condition Variables
– Use Semphores
**********************************************************************************************
sem.c:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
//At most you can have CMAX threads for producers or consumers
#define CMAX (10)
sem_t empty;
sem_t full;
sem_t mutex;
//Define global variables here
/* ==================================================== */
/* SIGNAL INTERRUPT HANDLER (Catches the SIGINT signal) */
/* ==================================================== */
void handler(int signo)
{
if(signo == SIGINT) {
printf(" Stopping... ");
stopFlag = 1;
}
}
void
Pthread_mutex_lock(pthread_mutex_t *m)
{
int rc = pthread_mutex_lock(m);
assert(rc == 0);
}
void
Pthread_mutex_unlock(pthread_mutex_t *m)
{
int rc = pthread_mutex_unlock(m);
assert(rc == 0);
}
void
Pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg)
{
int rc = pthread_create(thread, attr, start_routine, arg);
assert(rc == 0);
}
void
Pthread_join(pthread_t thread, void **value_ptr)
{
int rc = pthread_join(thread, value_ptr);
assert(rc == 0);
}
void
Sem_init(sem_t *sem, unsigned int value)
{
int rc = sem_init(sem, 0, value);
assert(rc == 0);
}
void Sem_wait(sem_t *sem)
{
int rc = sem_wait(sem);
assert(rc == 0);
}
void Sem_post(sem_t *sem)
{
int rc = sem_post(sem);
assert(rc == 0);
}
void do_fill(int value)
{
//Implement fill operations here, fill one item per time
}
int do_get()
{
//Implement get operations here, remove one item per time
}
void *
producer(int * arg)
{
int i;
while (!stopFlag) {
//Use semphores to produce an item here
//print a message: producer x fills y
}
// end case
if(stopFlag == 1){
// Gracefully quit the program when CTRL + c
// At this time, only fill -1 to the buffer
//Should print a message: Producer x fills -1
}
return NULL;
}
void *
consumer(int * arg)
{
while (!stopFlag) {
//Use semphores to consume an item here
//print a message: consumer x removes y
}
return NULL;
}
void
main(int argc, char *argv[])
{
if (argc != 4) {
fprintf(stderr, "usage: %s <buffersize> <producers> <consumers> ", argv[0]);
exit(1);
}
//variables initlization here
signal(SIGINT, handler);
//Initializing semphores here
//Start running producer and consumer threads here
//Join producer and consumer thread here
// Destroy semphores here
exit(0);
}
***************************************************
locks and CVs:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
//At most you can have CMAX threads for producers or consumers
#define CMAX (10)
pthread_cond_t empty = PTHREAD_COND_INITIALIZER;
pthread_cond_t fill = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
// Define global variables here
/* ==================================================== */
/* SIGNAL INTERRUPT HANDLER (Catches the SIGINT signal) */
/* ==================================================== */
int stopFlag = 0; // Flag for signaling other threads to stop running.
void handler(int signo)
{
if(signo == SIGINT) {
printf(" Stopping... ");
stopFlag = 1;
}
}
void
Pthread_mutex_lock(pthread_mutex_t *m)
{
int rc = pthread_mutex_lock(m);
assert(rc == 0);
}
void
Pthread_mutex_unlock(pthread_mutex_t *m)
{
int rc = pthread_mutex_unlock(m);
assert(rc == 0);
}
void
Pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg)
{
int rc = pthread_create(thread, attr, start_routine, arg);
assert(rc == 0);
}
void
Pthread_join(pthread_t thread, void **value_ptr)
{
int rc = pthread_join(thread, value_ptr);
assert(rc == 0);
}
void do_fill(int value)
{
//Implement fill operations here
//Fill one item each time
}
int do_get()
{
//Implement get item here, remove one item each time
// Return the value consumed by the consumer
}
void *
producer(int *arg)
{
while (!stopFlag) {
//Implement producer mutex and CVs here
//Should print a message: Producer x fills y
}
if(stopFlag == 1){ //end case
// Gracefully quit the program when CTRL + c
// At this time, only fill -1 to the buffer
//Should print a message: Producer x fills -1
}
return NULL;
}
void *
consumer(int *arg)
{
while (!stopFlag) {
//Implement producer mutex and CVs here
//Should print a message: Consumer x removes y
}
return NULL;
}
int
main(int argc, char *argv[])
{
if (argc != 4) {
fprintf(stderr, "usage: %s <buffersize> <producers> <consumers> ", argv[0]);
exit(1);
}
//Implement initilization here
/* ----------------------- */
/* REGISTER SIGNAL HANDLER */
/* ----------------------- */
signal(SIGINT, handler);
//Create producer threads and consumer threads here
//Join producer and consumer threads here
// Destroy the (by now unlocked) mutex lock.
// Destroy CV fill.
// Destroy CV empty.
exit(0);
}
Explanation / Answer
Here providing the working solution : Uses OpenMP parallel aproach
#include<stdio.h>
#include<omp.h>
omp_lock_t w; //buffer lock.
omp_lock_t r; //nr lock
char buf[10];
int nr=0,nre=0,nwr=0;
void startread()
{
omp_set_lock(&r); //to check whether already a reader is there or not. and for nr to be accessed by only one thread.
nr++;
if(nr==1)
{
omp_set_lock(&w);
printf(" Reader acquired the lock ");
}
omp_unset_lock(&r);
}
void endread()
{
omp_set_lock(&r);
nr--;
if(nr==0) //last reading thread to release the lock.
{
omp_unset_lock(&w);
printf(" Reader releasing lock ");
}
omp_unset_lock(&r);
}
void reader()
{
int tid;
startread();
tid = omp_get_thread_num();
printf(" Thread %d Reading contents:-%s ",tid,buf);
endread();
}
void writer()
{
omp_set_lock(&w);
printf(" Writer %d acquired the lock",omp_get_thread_num());
printf(" Enter text to Overwrite contents of buffer:");
scanf("%s",buf);
omp_unset_lock(&w);
printf("Writer %d releasing the lock ",omp_get_thread_num());
}
int main()
{
int id,i,numthr;
omp_set_num_threads(8);
printf(" Enter no of writers and readers:");
scanf("%d%d",&nwr,&nre);
printf(" Write data in buffer:");
scanf("%s",buf);
omp_init_lock(&w);
omp_init_lock(&r);
#pragma omp parallel
{
#pragma omp for
for(i=0;i<(nre+nwr);i++)
{
if(i<nwr) //threads having id < nwr will write
{
writer();
}
else
{
reader(); //threads having other id's will read
}
}
}
return 0;
}
/*
output:
Swapnil@arya-Inspiron-3521:~$ gcc -fopenmp rw.c
Swapnil@arya-Inspiron-3521:~$ ./a.out
Enter no of writers and readers:3 4
Write data in buffer:tecomp
Writer 1 acquired the lock
Enter text to Overwrite contents of buffer:te
Writer 1 releasing the lock
Writer 2 acquired the lock
Enter text to Overwrite contents of buffer:comp
Writer 2 releasing the lock
Reader acquired the lock
Thread 3 Reading contents:-comp
Thread 4 Reading contents:-comp
Reader releasing lock
Reader acquired the lock
Thread 6 Reading contents:-comp
Thread 5 Reading contents:-comp
Reader releasing lock
Writer 0 acquired the lock
Enter text to Overwrite contents of buffer:tecomp1
Writer 0 releasing the lock
*/
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.