Reputation: 83
Update included after the first block of code
I am new to multithreading and am having an issue outputting the results of various threads in a C program. Specifically, I am attempting to output the average, maximum, and minimum within an array of integers to the user using a different thread for each. However, the parent thread which is supposed to print the three values terminates upon completion of the its children threads.
For the sake of testing, I currently print the results within the children thread, but I need to print these values in the parent thread. The code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *avgThread(int *nums,int*out)
{
//sleep(1);
int total = 0,x,avg;
for(x=0;x<7;x++) total+=nums[x];
avg = total/7;
*out = avg;
printf("%d\n",avg);
}
void *minThread(int *nums,int*out)
{
int min = nums[0],x;
for(x=1;x<7;x++) if(nums[x]<min) min=nums[x];
*out = min;
printf("%d\n",min);
}
void *maxThread(int *nums,int*out)
{
int max = nums[0],x;
for(x=1;x<7;x++) if(nums[x]>max) max=nums[x];
*out = max;
printf("%d\n",max);
}
void *parentThread(int*nums)
{
int average,minimum,maximum;
pthread_t avg,min,max;
pthread_attr_t avgfun,minfun,maxfun;
pthread_attr_init(&avgfun);
pthread_attr_init(&minfun);
pthread_attr_init(&maxfun);
pthread_create(&avg, &avgfun, avgThread(nums,&average), NULL);
pthread_create(&min, &minfun, minThread(nums,&minimum), NULL);
pthread_create(&max, &maxfun, maxThread(nums,&maximum), NULL);
pthread_join(avg, NULL);
pthread_join(min, NULL);
pthread_join(max, NULL);
printf("%d\n",maximum);
printf("%d\n",average);
printf("%d\n",minimum);
pthread_join(pthread_self(),NULL);
return NULL;
}
int main()
{
int nums[] = {90, 81, 78, 95, 79, 72, 85};
pthread_t prnt;
pthread_attr_t parent;
pthread_attr_init(&parent);
pthread_create(&prnt,&parent,parentThread(nums),NULL);
pthread_join(prnt,NULL);
sleep(3);
exit(0);
}
Update
Thank you to Pavel and others for pointing out some things I am doing wrong. I have made the necessary modifications to the thread initialization and call. I am also able to output the calculated average, max, and min in the parent thread, but only by making said variables global in scope. If anyone can tell me if I can keep:
int average,maximum,minimum
inside *parentThread and still calculate them inside the child threads, that would be great. Here is my code as it stands now:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
int average,minimum,maximum;
void *avgThread(void *numsptr)
{
sleep(1);
int *nums=(int*)numsptr;
int total = 0,x;
for(x=0;x<7;x++) total+=(int)nums[x];
average = total/7;
return NULL;
}
void *minThread(void *numsptr)
{
sleep(2);
int *nums=(int*)numsptr,x;
minimum = nums[0];
for(x=1;x<7;x++) if((int)nums[x]<minimum) minimum=(int)nums[x];
return NULL;
}
void *maxThread(void *numsptr)
{
sleep(3);
int *nums=(int*)numsptr,x;
maximum = nums[0];
for(x=1;x<7;x++) if((int)nums[x]>maximum) maximum=(int)nums[x];
return NULL;
}
void *parentThread(void *numsptr){
int *nums=(int*)numsptr;
//int average,minimum,maximum;
pthread_t avg,min,max;
pthread_attr_t avgfun,minfun,maxfun;
pthread_attr_init(&avgfun);
pthread_attr_init(&minfun);
pthread_attr_init(&maxfun);
pthread_create(&avg, &avgfun, &avgThread,(void*)nums);
pthread_create(&min, &minfun, &minThread,(void*)nums);
pthread_create(&max, &maxfun, &maxThread,(void*)nums);
pthread_join(avg, NULL);
printf("The average value is %d\n",average);
pthread_join(min, NULL);
printf("The minimum value is %d\n",minimum);
pthread_join(max, NULL);
printf("The max value is %d\n",maximum);
return NULL;
}
int main()
{
int nums[] = {90, 81, 78, 95, 79, 72, 85};
pthread_t prnt;
pthread_attr_t parent;
pthread_attr_init(&parent);
pthread_create(&prnt,&parent,&parentThread,(void*)nums);
pthread_join(prnt,NULL);
exit(0);
}
Upvotes: 0
Views: 59
Reputation: 16843
You do not start threads properly. You have to pass function that will execute, but you are actually calling your function and passing its return value to pthread_create
:
// call parentThread(nums) and then create thread.
pthread_create(&prnt, &parent, parentThread(nums),NULL);
What you wanted to do is this:
void *parentThread(void *nums_ptr)
{
int *nums = (int*)nums_ptr;
...
return NULL;
}
int main()
{
int nums[] = {90, 81, 78, 95, 79, 72, 85};
pthread_t prnt;
pthread_create(&prnt, NULL, &parentThread, (void*)nums);
...
}
Same applies for all your other threads. Other issues that you have:
void *threadFunc(void *nums)
return NULL;
)pthread_join(pthread_self(),NULL);
If anyone can tell me if I can keep:
int average,maximum,minimum
inside *parentThread and still calculate them inside the child threads
Sure you can do that. Define some struct that stores all that data and pass pointer to that data to your threads:
struct myState
{
int average, minimum, maximum;
int *nums
};
void *avgThread(void *data)
{
sleep(1);
myState *state = (myState*)data;
int total = 0,x;
for(int x=0; x<7; x++)
total += state->nums[x];
state->average = total/7;
return NULL;
}
void *parentThread(void *nums_ptr)
{
int *nums = (int*)nums_ptr;
myState state;
state.nums = nums;
...
pthread_create(&avg, &avgfun, &avgThread, &state);
...
pthread_join(avg, NULL);
printf("The average value is %d\n", state.average);
...
return NULL;
}
Upvotes: 2