Question

a multi-threaded producer / consumer program without any locking or signaling. It therefore has synchronization problems....

a multi-threaded producer / consumer program without any locking or signaling. It therefore has synchronization problems. Add locks and signals so that it works correctly.
/* Homework 5.X */
/* Robin Ehrlich */

/* compile: gcc Homework5.c -lpthread */

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct class {
   struct class *next;
   int id;
   int grade;
};

#define SLEEP_TIME 1
#define MAX_PRODUCE 10

static struct class *classHead = NULL;
static struct class *classTail = NULL;
static pthread_mutex_t classMutex;
static pthread_cond_t classSignal;
static int producerComplete = 0;
static int randomSeed;

static void *consumerThread(void *arg)
{

   struct class *classCurrent;
   int sleepTime;

   printf("Consumer thread starting\n");

   while (1) {

       /* get next item */
      
       classCurrent = classHead;
       if ((classCurrent == NULL) && (producerComplete))
           break;
      
       classHead = classCurrent->next;

       /* do some work */
      
       printf("consume: id = %d, grade = %d\n", classCurrent->id,
           classCurrent->grade);
       sleepTime = (rand_r(&randomSeed) % SLEEP_TIME) + 1;
       sleep(sleepTime);
       free(classCurrent);
   }

   printf("Consumer thread completed\n");

   return (0);

}

static void *producerThread(void *arg)
{
  
   struct class *classCurrent;
   int i;
   int sleepTime;

   printf("Producer thread starting\n");

   for (i = 0; i < MAX_PRODUCE; i++) {

       /* do some work */
      
       printf("produce: id = %d, grade = %d\n", classCurrent->id,
               classCurrent->grade);
       sleepTime = (rand_r(&randomSeed) % SLEEP_TIME) + 1;
       sleep(sleepTime);

       /* give to consumer */

       classCurrent = malloc(sizeof(struct class));
       classCurrent->id = 462 + i;
       classCurrent->grade = 90 - i;
       classCurrent->next = NULL;
       if (classHead == NULL)
           classHead = classCurrent;
       else
           classTail->next = classCurrent;
       classTail = classCurrent;
   }

   producerComplete = 1;

   printf("Producer thread completed\n");

   return (0);

}

int main(int argc, char **argv)
{

   pthread_attr_t attr;
   struct class *classCurrent;
   pthread_t consumerTid;
   pthread_t producerTid;

   printf("Starting\n");

   randomSeed = (int) time(NULL);
   srand(randomSeed);

   pthread_mutex_init(&classMutex, NULL);
   pthread_cond_init(&classSignal, NULL);

   pthread_attr_init(&attr);
   pthread_create(&producerTid, &attr, producerThread, NULL);
   pthread_create(&consumerTid, &attr, consumerThread, NULL);

   /* wait for threads to complete */

   pthread_join(producerTid, NULL);
   pthread_join(consumerTid, NULL);

   printf("Completed\n");

   return (0);

}

0 0
Add a comment Improve this question Transcribed image text
Answer #1

Please find the following program that uses mutex and conditional variable to protect producer and consumer problem which has classList.

I have added comments as needed in the program

Program:


#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

struct class {
struct class *next;
int id;
int grade;
};

#define SLEEP_TIME 1
#define MAX_PRODUCE 10

static struct class *classHead = NULL;
static struct class *classTail = NULL;
static pthread_mutex_t classMutex;
static pthread_cond_t classSignal;
static int producerComplete = 0;
static int randomSeed;

static void *consumerThread(void *arg)
{

struct class *classCurrent;
int sleepTime;

printf("Consumer thread starting\n");
//sleep(500);
while (1) {

//take the lock
pthread_mutex_lock(&classMutex);

/* get next item */

if (classHead == NULL && producerComplete ==0)
{
           //wait if the class is not populated and go further if producer filled the item
pthread_cond_wait(&classSignal,&classMutex);
}
classCurrent = classHead;
if ((classCurrent == NULL) && (producerComplete))
break;

classHead = classCurrent->next;

/* do some work */
   //after consuming release the lock and signal the producer
pthread_cond_signal(&classSignal);
pthread_mutex_unlock(&classMutex);

printf("consume: id = %d, grade = %d\n", classCurrent->id,
classCurrent->grade);
sleepTime = (rand_r(&randomSeed) % SLEEP_TIME) + 1;
sleep(sleepTime);
free(classCurrent);

}

printf("Consumer thread completed\n");

return (0);

}

static void *producerThread(void *arg)
{

struct class *classCurrent;
int i;
int sleepTime;

printf("Producer thread starting\n");

for (i = 0; i < MAX_PRODUCE; i++) {

/* do some work

printf("produce: id = %d, grade = %d\n", classCurrent->id,
classCurrent->grade); */
sleepTime = (rand_r(&randomSeed) % SLEEP_TIME) + 1;
sleep(sleepTime);

//take the lock here
pthread_mutex_lock(&classMutex);

/* give to consumer */
classCurrent = malloc(sizeof(struct class));
classCurrent->id = 462 + i;
classCurrent->grade = 90 - i;
classCurrent->next = NULL;
if (classHead == NULL)
classHead = classCurrent;
else
classTail->next = classCurrent;
classTail = classCurrent;
     
   //signal the consumer
pthread_cond_signal(&classSignal);
   //unlock the mutex to allow consumer to read
pthread_mutex_unlock(&classMutex);

}

producerComplete = 1;

printf("Producer thread completed\n");

return (0);

}

int main(int argc, char **argv)
{

pthread_attr_t attr;
struct class *classCurrent;
pthread_t consumerTid;
pthread_t producerTid;

printf("Starting\n");

randomSeed = (int) time(NULL);
srand(randomSeed);

pthread_mutex_init(&classMutex, NULL);
pthread_cond_init(&classSignal, NULL);

pthread_attr_init(&attr);
pthread_create(&producerTid, &attr, producerThread, NULL);
pthread_create(&consumerTid, &attr, consumerThread, NULL);

/* wait for threads to complete */

pthread_join(producerTid, NULL);
pthread_join(consumerTid, NULL);

printf("Completed\n");

return (0);

}

Add a comment
Know the answer?
Add Answer to:
a multi-threaded producer / consumer program without any locking or signaling. It therefore has synchronization problems....
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Solve the Consumer/Producer problem using semaphores. A skeleton program (Save it as producer_consumer.c) is provided to...

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

  • In c programming The Consumer Submits processing requests to the producer by supplying a file name, its location and a character. It also outputs the contents of the file provided by the producer...

    In c programming The Consumer Submits processing requests to the producer by supplying a file name, its location and a character. It also outputs the contents of the file provided by the producer to the standard output. The Producer Accepts multiple consumer requests and processes each request by creating the following four threads. The reader thread will read an input file, one line at a time. It will pass each line of input to the character thread through a queue...

  • i want to fix the solution and provide an explanation why the pthread_join is not working...

    i want to fix the solution and provide an explanation why the pthread_join is not working as intended? #include <stdio.h> /* standard I/O routines */ #include <pthread.h> /* pthread functions and data structures */ void* PrintHello(void* data) { pthread_t tid = (pthread_t)data; /* data received by thread */ pthread_join(tid, NULL); /* wait for thread tid */ printf("Hello from new thread %u - got %u\n", pthread_self(), data); pthread_exit(NULL); /* terminate the thread */ } /* like any C program, program's execution...

  • I am supposed to write documentation and report for the code below but I am new...

    I am supposed to write documentation and report for the code below but I am new to operating system concepts I will appreciate if someone can help make a detailed comment on each line of code for better understanding. Thanks #include <pthread.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <ctype.h> #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) struct thread_info...

  • Pleas help I need to create and array to add to my code something like this...

    Pleas help I need to create and array to add to my code something like this for (i = 0; i < NUM_THREADS; ++i) { thr_data[i].tid = i; if ((rc = pthread_create(&thr[i], NULL, thr_func, &thr_data[i]))) { fprintf(stderr, "error: pthread_create, rc: %d\n", rc); return EXIT_FAILURE; ::::::::: CODE ::::::::::::: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h>    int sharedVar = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* thread handler */ void *threadHandler(void *vargp) {    int i = 0;    pthread_mutex_lock(&mutex);   ...

  • 1) Compile thread2.c (remember the -lpthread flag). Run it numerous times, and notice the output usually...

    1) Compile thread2.c (remember the -lpthread flag). Run it numerous times, and notice the output usually differs. a) Why is the variable myglobal usually not 40? Be specific, be precise. b) In what special case would myglobal be 40? Be specific, be precise. #include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <fcntl.h> /* Purpose: Use 2 threads to increment myglobal exactly 40 times in total. Compile: using -pthread option */ int myglobal = 0; void *thread_function(void *arg) {   ...

  • so in this code, it computes the sum 1+2+....+n but i want it to compute 2*(1+2+....+n)...

    so in this code, it computes the sum 1+2+....+n but i want it to compute 2*(1+2+....+n) using semaphores implement solution to the critical section problem #include #include int sum; /* this data is shared by the thread(s) */ void *runner(void *param); /* threads call this function */ int main(int argc, char *argv[]) { pthread_t tid; /* the thread identifier */ pthread_attr_t attr; /* set of thread attributes */ if (argc != 2) { fprintf(stderr,"usage: a.out \n"); return -1; } if...

  • Please explain your answers thoroughly for the following question. 1) Compile thread2.c (remember the -lpthread flag)....

    Please explain your answers thoroughly for the following question. 1) Compile thread2.c (remember the -lpthread flag). Run it numerous times, and notice the output usually differs. a) Why is the variable myglobal usually not 40? Be specific, be precise. b) In what special case would myglobal be 40? Be specific, be precise. #include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <fcntl.h> /* Purpose: Use 2 threads to increment myglobal exactly 40 times in total. Compile: using -pthread option */...

  • 1. (50 pts) Write a C or C++ program A6p1.c(pp) that accepts one command line argument which is an integer...

    1. (50 pts) Write a C or C++ program A6p1.c(pp) that accepts one command line argument which is an integer n between 2 and 6 inclusive. Generate a string of 60 random upper case English characters and store them somewhere (e.g. in a char array). Use pthread to create n threads to convert the string into a complementary string ('A'<>'Z', 'B'<->'Y', 'C''X', etc). You should divide this conversion task among the n threads as evenly as possible, Print out the...

  • Read given code RaceOrNot3.c and write all possible outputs of the program. Assume there will be...

    Read given code RaceOrNot3.c and write all possible outputs of the program. Assume there will be no thread creation or joining failures or semaphore failures. If you believe there is only one possible output, you just need to write that output. #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <errno.h> sem_t s1; int c=0,x=0; void *UpdateC1(void *arg) {    int i;    for(i=0;i<2000000;i++)   {        sem_wait(&s1);        c++;   x++;        sem_post(&s1);    } } void *UpdateC2(void *arg) {    int i,x=0;    for(i=0;i<2999999;i++)   {        sem_wait(&s1);        c++;   x++;       ...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT