Reputation:
What I understand pthread_join manual is my program should output the same value I supplied to print_xs
but the output obtained is:
Message from printxs 11131 a
Message from printxs 11234 b
32766 -16
32766 0
The Program:
#include<stdio.h>
#include<pthread.h>
typedef struct paramsThread{
char c;
int count;
} threadPara;
void* print_xs(void* unused){
threadPara *tp = (threadPara *)unused;
int i=tp->count;
printf("Message from printxs %d %c\n", tp->count, tp->c);
return (void*)tp;
}
int main(){
pthread_t thread1, thread2;
threadPara t1,t2,t3,t4;
t1.c = 'a';
t2.c = 'b';
t1.count = 11131;
t2.count = 11234;
t3.count=0;
pthread_create(&thread1, NULL, &print_xs, &t1);
pthread_create(&thread2, NULL, &print_xs, &t2);
pthread_join(thread1,(void*)&t3);
printf("%d %d\n", t3.count, t3.c);
pthread_join(thread2,(void*)&t4);
printf("%d %d\n", t4.count, t4.c);
return 0;
}
Can some one explain why this is happening?
Upvotes: 1
Views: 104
Reputation: 70893
The thread function returns an address, a void*
.
pthread_join()
receives this address to where its 2nd parameter (a void**
) points to.
So to make use of this in your code instead of
pthread_join(thread1, (void*)&t3);
do
{
void * pv;
pthread_join(thread1, &pv);
if (NULL != pv)
{
t3 = *((threadPara*) pv);
}
}
As a side note: In C there is no need to cast to/from void
-pointers from/to other pointers, the pointers involved get converted implicitly.
So this code
void* print_xs(void* unused){
threadPara *tp = (threadPara *)unused;
int i=tp->count;
printf("Message from printxs %d %c\n", tp->count, tp->c);
return (void*)tp;
}
may very well be written like this:
void* print_xs(void* unused){
threadPara *tp = unused;
int i=tp->count;
printf("Message from printxs %d %c\n", tp->count, tp->c);
return tp;
}
Upvotes: 0
Reputation: 409166
If you read a pthread_join
reference or manual page you will see that the second argument is a pointer to a pointer. This is a way to emulate pass by reference in C.
The pointer the thread function returns is copied into another pointer.
The solution is to use pointers for t3
and t4
instead:
threadPara t1, t2;
threadPara *t3, *t4;
// ...
pthread_join(thread1,(void**)&t3); // Pass pointer to the pointer, emulating pass by reference
printf("%d %d\n", t3->count, t3->c);
pthread_join(thread2,(void**)&t4);
printf("%d %d\n", t4->count, t4->c);
If you print the pointers, or use a debugger, then you will see that t3
will be pointing to t1
(i.e. t3 == &t1
) and the same for t4
and t2
.
Upvotes: 5