Reputation: 192
Here's a function that should recursively find more precise values of Pi and split into a user defined amount of threads to do the recursion concurrently.
void* quad(void* argis){
struct args* arg=argis;
double m=(arg->l+arg->r)/2;
double fm=func(m);
double larea=(arg->fl+fm)*(m-arg->l)/2;
double rarea = (fm+arg->fr)*(arg->r-m)/2;
struct args* arg1 = (struct args*)malloc(sizeof(struct args));
arg1->l=arg->l;
arg1->r=m;
arg1->fl=arg->fl;
arg1->fr=fm;
arg1->area=larea;
struct args* arg2 = (struct args*)malloc(sizeof(struct args));
arg2->l=m;
arg2->r=arg->r;
arg2->fl=fm;
arg2->fr=arg->fl;
arg2->area=rarea;
if(fabs((larea+rarea)-arg->area)>error){
if(threads<=1){
void* p1=quad((void*)arg1);
void* p2=quad((void*)arg2);
larea=*((double*)p1);
rarea=*((double*)p2);
free(p1);
free(p2);
}
else{
pthread_t thread1, thread2;
pthread_mutex_lock(&lock1);
threads--;
pthread_mutex_unlock(&lock1);
pthread_create(&thread1, NULL, &quad, (void*)&arg1);
pthread_create(&thread2, NULL, &quad, (void*)&arg2);
void* ptr1;
void* ptr2;
pthread_join(thread1,&ptr1);
pthread_join(thread2,&ptr2);
pthread_mutex_lock(&lock1);
threads++;
pthread_mutex_unlock(&lock1);
larea=*(double*)ptr1;
rarea=*(double*)ptr2;
}
}
free(arg1);
free(arg2);
double ret= (larea+rarea);
double* poin=(double*)malloc(sizeof(double));
*poin=ret;
return (void*)poin;
}
However, it doesn't work. After investigating I've found that the problem seems to be here:
pthread_create(&thread1, NULL, &quad, (void*)&arg1);
pthread_create(&thread2, NULL, &quad, (void*)&arg2);
All arguments in struct arg1
and arg2
just become 0 after they've been passed in to the new thread. arg1
and arg2
aren't local they're in heap and I'm pretty sure threads share heap so that's not the problem. Is this not how you pass arguments to new thread in pthread_create()
?
This is my first time working with pthreads so be patient with me. But any help finding out what's causing the structs to be reset would be greatly appreciated. Thanks!
Upvotes: 0
Views: 2298
Reputation: 70903
As arg1
and arg2
are pointers already you want to pass them to to pthread_create()
"as is":
pthread_create(&thread1, NULL, &quad, arg1);
Also there is no need to cast here:
void* p1=quad((void*)arg1);
Just do:
void* p1=quad(arg1);
Same for malloc()
, no need to cast its result.
Nor here:
return (void*)poin;
Doing
return poin;
is fine.
In C conversion of any pointer to/from void*
is done implicitly.
Upvotes: 4