fork download
  1. /**************************************************************************************
  2. * Course: CS 4540 – Fall 2014
  3. * Assignment <3>
  4. * Name: <Waleed Gudah>
  5. * E-mail: <waleed.h.gudah@wmich.edu>
  6. * Submitted: <11/6/14>
  7. This is a multithreaded program that calculates various statistical values
  8. for a list of numbers. This program is passed a series of numbers on
  9. the command line and will then create three separate worker threads:
  10. 1) Thread 1 determine the average of the numbers
  11. 2) Thread 2 determine the maximum value
  12. 3) Thread 3 determine the minimum value
  13.  NOTE:
  14. I used a dynamically increasing integer array, the same array I used in part
  15. 3 of Assignment 1, I mention this becuase my program looks slightly different,
  16. on the cmd console, then the demo we were provided. Instead of first specifying
  17. a # of elements for the array my array size increases as needed.
  18. /****************************************************************************************/
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <pthread.h>
  23. #include <errno.h>
  24.  
  25. /*Error handling for pthread_create and pthread_join*/
  26. /*from the pthread_create man page*/
  27. #define handle_error_en(en, msg) \
  28.   do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
  29.  
  30. /* # of running threads */
  31. volatile int running_threads = 0;
  32.  
  33. pthread_t thread[3]; /*Descriptors for our 3 threads*/
  34.  
  35. int numOfElements;/*Total # of elements from the user*/
  36.  
  37. struct Results{ /*Struct to hold the statistical results*/
  38.  
  39. int min;
  40. int max;
  41. int average;
  42.  
  43. }Results;
  44.  
  45. /*This function finds the minimum element of an array*/
  46. void *findMin(void *array_ptr){
  47.  
  48. int i; /*counter*/
  49.  
  50. int *elements = (int*)array_ptr; /*re reference void array pointer*/
  51.  
  52. Results.min = elements[0]; /*set minimum to first element */
  53.  
  54. for(i = 0; i < numOfElements; i++){ /*iterate through array*/
  55.  
  56. if(elements[i] < Results.min){ /*if the current element is less than the current min*/
  57.  
  58. Results.min = elements[i]; /*store the new min*/
  59.  
  60. }
  61.  
  62. }
  63.  
  64. running_threads -= 1; /*Decrement thread count*/
  65.  
  66. return NULL;
  67.  
  68. }
  69.  
  70. /*This function finds the maximum element of an array*/
  71. void *findMax(void *array_ptr){
  72.  
  73. int i; /*counter*/
  74.  
  75. int *elements = (int*)array_ptr; /*re reference void array pointer*/
  76.  
  77. for(i = 0; i < numOfElements; i++){ /*iterate through array*/
  78.  
  79. if(elements[i] > Results.max){ /*store the new max*/
  80.  
  81. Results.max = elements[i];
  82.  
  83. }
  84. }
  85.  
  86. running_threads -= 1; /*Decrement thread count*/
  87.  
  88. return NULL;
  89.  
  90. }
  91.  
  92. /*This function finds the average of an array*/
  93. void *findAverage(void *array_ptr){
  94.  
  95. int i; /*counter*/
  96.  
  97. int *elements = (int*)array_ptr; /*re reference void array pointer*/
  98.  
  99. for(i = 0; i < numOfElements; i++){ /*iterate through array*/
  100.  
  101. Results.average += elements[i]; /*add element @ i to average*/
  102.  
  103. }
  104.  
  105. Results.average = Results.average/numOfElements; /*Divide the sum by the number of elements*/
  106.  
  107. running_threads -= 1; /*Decrement running threads counter*/
  108.  
  109. return NULL;
  110.  
  111. }
  112.  
  113. /* This method accepts a int n(initial size of array) and
  114.   pointer to an array and returns # of elements in the array
  115. */
  116. int getArrayInput(int n, int *array_ptr){
  117.  
  118. int input;/*Store user input */
  119.  
  120. int numberOfElements = 0;/*Number of Integers inputed*/
  121.  
  122. printf("Creating Dynamic Array...\n-\n");
  123.  
  124. for(;;){ /*infinite loop*/
  125.  
  126. printf("Enter a positive value:\nNegative Number to Stop\n-\n");
  127.  
  128. //Get Int from console, store at address of input
  129.  
  130. if (scanf("%d",&input) != 1){
  131.  
  132. printf("\nOops that wasn't an Integer\nlets try filling the array again\nRemember INTEGERS only!\n");
  133.  
  134. exit(EXIT_FAILURE);
  135.  
  136. }
  137.  
  138. if (input >= 0){
  139.  
  140. if (numberOfElements == n){
  141.  
  142. n += 1; //Make room for the current input
  143.  
  144. array_ptr = realloc(array_ptr, n * sizeof(int));//realloc array and set pointer
  145.  
  146. }
  147.  
  148. array_ptr[numberOfElements++] = input;//Store input at next empty element
  149.  
  150. } else {
  151.  
  152. printf("\nNumber of Integers: %d\n", numberOfElements);
  153.  
  154. break;
  155.  
  156. }
  157.  
  158. }
  159.  
  160. return numberOfElements;
  161.  
  162. }
  163.  
  164. /*This function joins our n number of threads */
  165. void joinThreads(int numberOfThreads){
  166.  
  167. int i; /*count*/
  168.  
  169. int s; /*error #*/
  170.  
  171. while(numberOfThreads >= 0){ /*Join our threads*/
  172.  
  173. s = pthread_join(thread[numberOfThreads], NULL);
  174.  
  175. /*if we recieve anything other than 0 we have a join error*/
  176. if (s != 0){
  177. /*handle error*/
  178. handle_error_en(s, "pthread_create");
  179.  
  180. }
  181.  
  182. numberOfThreads--;
  183.  
  184. }
  185.  
  186. }
  187.  
  188. /*This function creates the 3 threads we need and supplys
  189.   error catching for pthread_create, it could be
  190.   modified easily to create any # of threads automatically
  191. */
  192. void createThreads(int *array_ptr){
  193.  
  194. int s; /*error #*/
  195. /*Create a thread and passing in the function to begin
  196. exectuing as well as that functions required arguments*/
  197.  
  198. s = pthread_create(&thread[0], NULL, findMin, (void *)array_ptr);
  199.  
  200. if (s != 0){
  201.  
  202. handle_error_en(s, "pthread_create");
  203.  
  204. }
  205. running_threads += 1;
  206.  
  207. /*Create a thread and passing in the function to begin
  208. exectuing as well as that functions required arguments*/
  209. s = pthread_create(&thread[1], NULL, findMax, (void *)array_ptr);
  210.  
  211. if (s != 0){
  212.  
  213. handle_error_en(s, "pthread_create");
  214.  
  215. }
  216. running_threads += 1;
  217.  
  218. /*Create a thread and passing in the function to begin
  219. exectuing as well as that functions required arguments*/
  220. s = pthread_create(&thread[2], NULL, findAverage, (void *)array_ptr);
  221.  
  222. if (s != 0){
  223.  
  224. handle_error_en(s, "pthread_create");
  225.  
  226. }
  227.  
  228. running_threads += 1;
  229.  
  230. }
  231.  
  232. /* The main function initialiazes the dynamic array as well
  233.   as allocating space for it, Then it creates, using pthread_create,
  234.   3 Threads 1 to calculate the min, the max, and the average.
  235.   We then wait until each thread completes its task and then
  236.   join the 3 threads and prompt the user with the results
  237.  */
  238. int main(){
  239.  
  240. int n = 1; /* Initial Array Size*/
  241.  
  242. int *array_ptr = malloc(n * sizeof(int));/*Initialize array pointer*/
  243.  
  244. /*get an n sized array of elements from the user and save count*/
  245. numOfElements = getArrayInput(n, array_ptr);
  246.  
  247. createThreads(array_ptr);
  248.  
  249. while(running_threads>0){ /*Wait for each thread to decrement*/
  250.  
  251. sleep(1);
  252.  
  253. }
  254.  
  255. joinThreads(2); /*Call our thread joining function passing # of threads */
  256.  
  257. /*Prompt the user with our results*/
  258. printf("\nThe average is %d\nThe maximum is %d\nThe minimum is %d\n",Results.average, Results.max, Results.min);
  259.  
  260. return(0);
  261.  
  262. }
Runtime error #stdin #stdout 0s 9416KB
stdin
Standard input is empty
stdout
Creating Dynamic Array...
-
Enter a positive value:
Negative Number to Stop
-

Oops that wasn't an Integer
lets try filling the array again
Remember INTEGERS only!