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.