In: Computer Science
C Programming Language Question
The following program sums up a number from a user input argv[1] by using a single thread. For example, argv[1] of 100 is going to give us a sum of 5050 using just a single thread.
I need to modify it so that it takes 2 command lines args, argv[2] for number of threads. In other words, the program needs to use multi-threads to solve it. The number of threads is going to divide the work between them and then join together to sum the numbers.
For example, a command line of 100 10 will give us a sum of 5050 using 10 threads.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int sum; // this data is shared by the threads
void *runner(void *param); // threads call this
function
int main(int argc, char *argv[])
{
pthread_t tid; // thread identifier
pthread_attr_t attr; // set of thread attributes
// set the default attributes of the thread
pthread_attr_init(&attr);
// create the thread
pthread_create(&tid, &attr, runner, argv[1]);
// wait for the thread to exit
pthread_join(tid, NULL);
printf("Sum = %d\n", sum);
}
void *runner(void *param)
{
int i, upper = atoi(param);
sum = 0;
for (int i = 1; i <= upper; i++)
sum += i;
pthread_exit(0);
}
Please look at my code and in case of indentation issues check the screenshots.
---------------main.c-----------------
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct range
{
   //create a structure to pass as parameter to the
thread
   int tid;   //The structure contains thread
id, the and the range of numbers to compute sum
   int start;
   int end;
   int sum;
};
void *runner(void *param); // threads call this function
int main(int argc, char *argv[])
{
   if (argc != 3)
   {
       printf("Incorrect number of command
line arguments. Sample Usage: ./a.out 100 10 \n");
       exit(0);
   }
   int N = atoi(argv[1]);
   int N_OF_THREADS = atoi(argv[2]);
   pthread_t tids[N_OF_THREADS];   //create
thread ids as array
   pthread_attr_t attr;   // set of thread
attributes
   pthread_attr_init(&attr);   // set the
default attributes of the thread
   int status, i;
   int prev = 0;
   struct range *r = malloc(sizeof(struct range)
*N_OF_THREADS);   //create array of structures
   for (i = 0; i < N_OF_THREADS; i++)  
//loop for number of threads
   {
       printf("\nMain. Creating thread
%d", i);
       r[i].tid = i;  
//update the thread id
       r[i].start = prev + 1;  
//update the range for according to the thread id
       r[i].end = r[i].start + N /
N_OF_THREADS - 1;
       prev = r[i].end;
       if (i == N_OF_THREADS - 1)
           r[i].end =
N;
       status =
pthread_create(&tids[i], &attr, runner,
&r[i]);   //start the thread, pass structure
parameter
       if (status)
       {
           printf("Error
%d\n", status);
           exit(-1);
       }
   }
   for (i = 0; i < N_OF_THREADS; i++)
   {
       pthread_join(tids[i],
NULL);   //main waits for thread i to exit
   }
   int total = 0;
   for (i = 0; i < N_OF_THREADS; i++)
   {
       total = total +
r[i].sum;   //main adds the sum of the values computed by
the threads
   }
   printf("\n\nThe sum of numbers from 1 to %d is %d\n",
N, total);   //print total
   exit(0);
}
void *runner(void *param)   // threads call this
function
{
   struct range *ptr = (struct range *)
param;   //get the structure parameter as pointer
   int sum = 0;
   int i;
   for (i = ptr->start; i <= ptr->end;
i++)   //compute the sum from start to end
       sum = sum + i;
   //print threaad output
   printf("\nThread %d computed sum from %d to %d, SUM =
%d", ptr->tid, ptr->start, ptr->end, sum);
   ptr->sum = sum;   //store the sum inside
the structure sum field
   pthread_exit(NULL);
}
--------------Screenshots--------------------


------------------Output------------------


---------------Updated answer---------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct range
{
   //create a structure to pass as parameter to the
thread
   int tid;   //The structure contains thread
id, the and the range of numbers to compute sum
   int start;
   int end;
   int sum;
};
void *runner(void *param); // threads call this function
int main(int argc, char *argv[])
{
   if (argc != 3)
   {
       printf("Incorrect number of command
line arguments. Sample Usage: ./a.out 100 10 \n");
       exit(0);
   }
   int N = atoi(argv[1]);
   int N_OF_THREADS = atoi(argv[2]);
   pthread_t tids[N_OF_THREADS];   //create
thread ids as array
   pthread_attr_t attr;   // set of thread
attributes
   pthread_attr_init(&attr);   // set the
default attributes of the thread
   int status, i;
   int prev = 0;
   struct range *r = malloc(sizeof(struct range)
*N_OF_THREADS);   //create array of structures
   for (i = 0; i < N_OF_THREADS; i++)  
//loop for number of threads
   {
       printf("\nMain. Creating thread
%d", i);
       r[i].tid = i;  
//update the thread id
       r[i].start = prev + 1;  
//update the range for according to the thread id
       r[i].end = r[i].start + N /
N_OF_THREADS - 1;
       prev = r[i].end;
       if (i == N_OF_THREADS - 1)
           r[i].end =
N;
       status =
pthread_create(&tids[i], &attr, runner,
&r[i]);   //start the thread, pass structure
parameter
       pthread_join(tids[i],
NULL);   //main waits for all the threads to exit
       if (status)
       {
           printf("Error
%d\n", status);
           exit(-1);
       }
   }
   /*for (i = 0; i < N_OF_THREADS; i++)
   {
       pthread_join(tids[i],
NULL);   //main waits for thread i to exit
   }*/
   int total = 0;
   for (i = 0; i < N_OF_THREADS; i++)
   {
       total = total +
r[i].sum;   //main adds the sum of the values computed by
the threads
   }
   printf("\n\nThe sum of numbers from 1 to %d is %d\n",
N, total);   //print total
   exit(0);
}
void *runner(void *param)   // threads call this
function
{
   struct range *ptr = (struct range *)
param;   //get the structure parameter as pointer
   int sum = 0;
   int i;
   for (i = ptr->start; i <= ptr->end;
i++)   //compute the sum from start to end
       sum = sum + i;
   //print threaad output
   printf("\nThread %d computed sum from %d to %d, SUM =
%d", ptr->tid, ptr->start, ptr->end, sum);
   ptr->sum = sum;   //store the sum inside
the structure sum field
   pthread_exit(NULL);
}

-------------------------------------------------------------------------------------------------------
Please give a thumbs up if you find this answer helpful.
If it doesn't help, please comment before giving a thumbs
down.
Please Do comment if you need any clarification.
I will surely help you.