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

***I need a solution for this problem that 7 integers can pass not 3 and then th

ID: 3678969 • Letter: #

Question

***I need a solution for this problem that 7 integers can pass not 3 and then their average value, minimum value and maximum value need to be determine. ***

Write a multithreaded program that calculates various statistical values for a list of numbers. This program will be passed a series of numbers on the command line and will then create three separate worker threads. One thread will determine the average of the numbers, the second will determine the maximum value, and the third will determine the minimum value. For example, suppose your program is passed the integers

                                90 81 78 95 79 72 85

The program will report

                                The average value is 82

                                The minimum value is 72

                                The maximum value is 95

The variables representing the average, minimum, and maximum values will be stored globally. The worker threads will set these values, and the parent thread will output the values once the workers have exited. (We could obviously expand this program by creating additional threads

that determine other statistical values, such as median and standard deviation.)

Explanation / Answer

/**************************************************************************************
   This is a multithreaded program that calculates various statistical values
   for a list of numbers. This program is passed a series of numbers on
   the command line and will then create three separate worker threads:
/****************************************************************************************/

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

/*Error handling for pthread_create and pthread_join*/
/*from the pthread_create man page*/
#define handle_error_en(en, msg)
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

/* # of running threads */
volatile int running_threads = 0;

pthread_t thread[3]; /*Descriptors for our 3 threads*/

int numOfElements;/*Total # of elements from the user*/

struct Results{ /*Struct to hold the statistical results*/
  
   int min;
   int max;
   int average;

}Results;

/*This function finds the minimum element of an array*/
void *findMin(void *array_ptr){
  
   int i; /*counter*/
  
   int *elements = (int*)array_ptr; /*re reference void array pointer*/

   Results.min = elements[0]; /*set minimum to first element */

   for(i = 0; i < numOfElements; i++){   /*iterate through array*/

       if(elements[i] < Results.min){   /*if the current element is less than the current min*/

           Results.min = elements[i];   /*store the new min*/
  
       }
  
   }

   running_threads -= 1;   /*Decrement thread count*/

return NULL;

}

/*This function finds the maximum element of an array*/
void *findMax(void *array_ptr){
  
   int i;   /*counter*/

   int *elements = (int*)array_ptr; /*re reference void array pointer*/
  
   for(i = 0; i < numOfElements; i++){   /*iterate through array*/

       if(elements[i] > Results.max){   /*store the new max*/

           Results.max = elements[i];

       }
   }

   running_threads -= 1;   /*Decrement thread count*/

return NULL;

}

/*This function finds the average of an array*/
void *findAverage(void *array_ptr){
  
   int i;   /*counter*/

   int *elements = (int*)array_ptr;    /*re reference void array pointer*/

   for(i = 0; i < numOfElements; i++){       /*iterate through array*/

       Results.average += elements[i];       /*add element @ i to average*/

   }

   Results.average = Results.average/numOfElements;   /*Divide the sum by the number of elements*/

   running_threads -= 1;   /*Decrement running threads counter*/

return NULL;

}

/* This method accepts a int n(initial size of array) and
pointer to an array and returns # of elements in the array
*/
int getArrayInput(int n, int *array_ptr){
      
       int input;/*Store user input */

       int numberOfElements = 0;/*Number of Integers inputed*/

   printf("Creating Dynamic Array... - ");

       for(;;){ /*infinite loop*/

       printf("Enter a positive value: Negative Number to Stop - ");

       //Get Int from console, store at address of input

           if (scanf("%d",&input) != 1){

               printf(" Oops that wasn't an Integer lets try filling the array again Remember INTEGERS only! ");

               exit(EXIT_FAILURE);
          
           }

       if (input >= 0){

           if (numberOfElements == n){

       n += 1; //Make room for the current input
      
       array_ptr = realloc(array_ptr, n * sizeof(int));//realloc array and set pointer
  
            }

       array_ptr[numberOfElements++] = input;//Store input at next empty element
  
       } else {
  
        printf(" Number of Integers: %d ", numberOfElements);

        break;

                }

           }

   return numberOfElements;
  
       }

/*This function joins our n number of threads */
void joinThreads(int numberOfThreads){
  
   int i; /*count*/

   int s; /*error #*/

   while(numberOfThreads >= 0){   /*Join our threads*/

       s = pthread_join(thread[numberOfThreads], NULL);

       /*if we recieve anything other than 0 we have a join error*/
       if (s != 0){
          /*handle error*/
           handle_error_en(s, "pthread_create");
         
       }

       numberOfThreads--;

   }
  
}
  
/*This function creates the 3 threads we need and supplys
error catching for pthread_create, it could be
modified easily to create any # of threads automatically
*/
void createThreads(int *array_ptr){
  
   int s; /*error #*/
   /*Create a thread and passing in the function to begin
   exectuing as well as that functions required arguments*/

    s = pthread_create(&thread[0], NULL, findMin, (void *)array_ptr);

   if (s != 0){

           handle_error_en(s, "pthread_create");
         
       }
          running_threads += 1;

   /*Create a thread and passing in the function to begin
   exectuing as well as that functions required arguments*/
   s = pthread_create(&thread[1], NULL, findMax, (void *)array_ptr);

       if (s != 0){
  
handle_error_en(s, "pthread_create");
   
    }
   running_threads += 1;

   /*Create a thread and passing in the function to begin
   exectuing as well as that functions required arguments*/
   s = pthread_create(&thread[2], NULL, findAverage, (void *)array_ptr);
            
       if (s != 0){

handle_error_en(s, "pthread_create");
   
    }
          
           running_threads += 1;

}

/* The main function initialiazes the dynamic array as well
as allocating space for it, Then it creates, using pthread_create,
3 Threads 1 to calculate the min, the max, and the average.
We then wait until each thread completes its task and then
join the 3 threads and prompt the user with the results
*/
int main(){

   int n = 1; /* Initial Array Size*/

   int *array_ptr = malloc(n * sizeof(int));/*Initialize array pointer*/
      
       /*get an n sized array of elements from the user and save count*/
       numOfElements = getArrayInput(n, array_ptr);
      
       createThreads(array_ptr);
      
       while(running_threads>0){   /*Wait for each thread to decrement*/
  
               sleep(1);

           }

       joinThreads(2);   /*Call our thread joining function passing # of threads */

       /*Prompt the user with our results*/
       printf(" The average is %d The maximum is %d The minimum is %d ",Results.average, Results.max, Results.min);

   return(0);

}

/*************************** makefile ******************************************/