skip to Main Content

I’m writing a multi-threaded program in c that takes in a list of numbers from the command line, then uses 3 seperate threads to get the average, max number, and min number. I completed it, but I’m not getting the correct output and I’m quite confused, because the reason it’s not working is because my index variable in my threads is not incrementing. It just stays at 0 no matter what, even when trying both a while and for loop. Here is my code:

Note: I’m coding on Linux

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

int sum =0;
int num;
int count;
int max;
int min;
float average;

void* Thread_Avg(void *arg)
{

     int i = 0;
     int *array = (int *)arg;
          while (i < count)
          {
               printf("%.fn",i);
               sum += array[i];
               i +=1;
          }

     average = sum/count;
     pthread_exit(0);
}

void* Thread_max(void *arg)
{
     i = 0;
     int *array = (int *)arg;
     for (i = 0; i < count; i++)
     //printf("%.f",max);
     {
          if(i ==0)
           {
               max = array[i];
           }
          else if(max < array[i])
          {
                max = array[i];
          }
     }
pthread_exit(0);
}

void* Thread_min(void *arg)
{
     int i = 0;
     int *array = (int *)arg;
     for (i = 0; i < count; i++)
     {
          if (array[i] < min)
          {
                min = array[i];
          }
      }
pthread_exit(0);
}

int main(int argc, char *argv[])
{
     if (argc < 2)

     {

     printf("Usage: %s <at least one integer as input>n", argv[0]);

     return 0;
     }

     int *num = (int *)malloc((argc-1)*sizeof(int));
     int i;



for (i =1; i <argc; i++)
{
     num[i-1] = atoi(argv[i]);
     count++;
}
 //count = argc;

pthread_t thread1, thread2, thread3;
pthread_create(&thread1, NULL, Thread_Avg, (void *)num);
pthread_create(&thread2, NULL, Thread_max, (void *)num);
pthread_create(&thread3, NULL, Thread_min, (void *)num);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);

printf("The average value is %.fn", average);
printf("The minimum value is %.fn", min);
printf("The maximum value is %.fn", max);
return 0;
}   

incorrect Output: (the zeroes are just from my print statement to check if i was actually being incremented, which it’s not. It’s stuck at 0) My average, max, and min are also not calculating properly

gcc Program.c -pthread

os@debian:~$ ./a.out 1 2 3 4 5

0

0

0

0

The average value is 2

The minimum value is 2

The maximum value is 2

3

Answers


  1. You probably need to read a lot more about how threads work and what they are useful for. Your threads are sharing global variables (including i), and updating them without any regard to the other threads that are relying upon them.
    If you change the section of your main program to this:

    pthread_create(&thread1, NULL, Thread_Avg, (void *)num);
    pthread_join(thread1, NULL);
    pthread_create(&thread2, NULL, Thread_max, (void *)num);
    pthread_join(thread2, NULL);
    pthread_create(&thread3, NULL, Thread_min, (void *)num);
    pthread_join(thread3, NULL);
    

    Do you get the expected results? Yes, so the next step is why. It is because they are no longer simultaneously updating / relying on these global variables. So, your task is:

    1. Figure out which variables do not need to be shared.
    2. Investigate methods of protecting the ones that need it.
    3. Repeat, until you can convince somebody that what you have works.

    Also, programs are meant to be read. Indenting is a basic visual organisation which enables people to rapidly grasp the concepts a program is expressing. Please learn about it; but until you do, imitate the masters, like the authors of C (Kerningham and Ritchie); or at the very least, install indent and run your code through it periodically. You will be amazed how much easier it is to understand a program that has a reasonable notion of indentation.

    Login or Signup to reply.
  2. #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    
    float sum = 0; //use sample type with average
    int num;
    int count;
    int max;
    int min;
    float average;
    
    void* Thread_Avg(void *arg)
    {
        int i = 0;
        int *array = (int *)arg;
        while (i < count)
        {
            printf("%dn",i); //%d for int 
            sum += array[i];
            i +=1;
        }
    
        average = sum/count;
        pthread_exit(0);
    }
    
    void* Thread_max(void *arg)
    {
         int i = 0;
         int *array = (int *)arg;
         for (i = 0; i < count; i++)
         //printf("%.f",max);
         {
              if(i ==0)
               {
                   max = array[i];
               }
              else if(max < array[i])
              {
                    max = array[i];
              }
         }
        pthread_exit(0);
    }
    
    void* Thread_min(void *arg)
    {
         int i = 0;
         int *array = (int *)arg;
         for (i = 0; i < count; i++)
         {
              if (array[i] < min)
              {
                    min = array[i];
              }
          }
        pthread_exit(0);
    }
    
    int main(int argc, char *argv[])
    {
         if (argc < 2)
         {
            printf("Usage: %s <at least one integer as input>n", argv[0]);
            return 0;
         }
    
         int *num = (int *)malloc((argc-1)*sizeof(int));
         int i;
    
        for (i =1; i <argc; i++)
        {
            num[i-1] = atoi(argv[i]);
            count++;
        }
        //count = argc;
        pthread_t thread1, thread2, thread3;
        pthread_create(&thread1, NULL, Thread_Avg, (void *)num);
        pthread_create(&thread2, NULL, Thread_max, (void *)num);
        pthread_create(&thread3, NULL, Thread_min, (void *)num);
        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
        pthread_join(thread3, NULL);
    
        printf("The average value is %.fn", average);
        printf("The minimum value is %dn", min); //%d for int
        printf("The maximum value is %dn", max); //%d for int
        return 0;
    }
    

    I tried to run it on my machine and it works:

    $ ./main 1 2 3 4 5
    0
    1
    2
    3
    4
    The average value is 3
    The minimum value is 0
    The maximum value is 5
    
    Login or Signup to reply.
  3. Your min algorithm won’t work correctly as the min variable is initialized to 0. If all input values are >0, your min will be incorrectly 0. The algorithm for max has the extra check and works correctly.

    You also have a few printf format bugs in your program that will lead to incorrect display of values. You should enable warnings in your compiler, for instance by adding the -Wall flag or equivalent, to help identify these.

    1. printf("%.fn",i); should be printf("%dn",i);
    2. printf("The minimum value is %.fn", min); should be printf("The minimum value is %dn", min);
    3. printf("The maximum value is %.fn", max); should be printf("The maximum value is %dn", max);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search