I am seeing different behaviors when variable used to get return values using pthread_join is defined gloabal vs static scope. I have included code_snippet here.
Static variables
int main()
{
static int r1,r2;
pthread_t t1, t2;
int i1[] = {1,2};
int i2[] = {3,4};
r1 = pthread_create( &t1, NULL, myfn, (void*)i1);
r2 = pthread_create( &t2, NULL, myfn, (void*)i2);
pthread_join( t1, (void *)&r1 );
pthread_join( t2, (void *)&r2 );
printf("Thread 1 returns: %d\n",r1);
printf("Thread 2 returns: %d\n",r2);
return 0;
}
void *myfn( void *intarray )
{
pthread_t t=pthread_self();
int *g = (int *) intarray;
int i=0;
int d=1;
for (i=g[0];i<=g[1];i++)
d*=i;
fprintf(stderr, "TID=%u %d\n",t, d);
pthread_exit((void *)d);
}
Return value
TID=3425117952 12
TID=3433510656 2
Thread 1 returns: 2
Thread 2 returns: 12
Global variables
int r1,r2;
int main()
{
same as above
}
void *myfn( void *intarray )
{
same as above
}
Return value
TID=3425117952 12
TID=3433510656 2
Thread 1 returns: 0 <<<<< it returns 0
Thread 2 returns: 12
Could someone please explain why it behaves differently ?
Almost certainly it's because the size of int
and void *
differ on your platform, so when pthread_join()
writes a void *
value through the int *
pointer you gave it, it overwrites adjacent memory.
The different declaration of r1
and r2
changes the layout of the variables enough to change the effect you see.
Casting an int
to void *
in order to return it is messy; you're better off either allocating space for a result in the main thread and passing that to the thread when it starts, or have the thread allocate the result and return a pointer to it when it finishes.
However, if you insist on the cast to void method, you can fix it by passing the address of an actual void *
object to pthread_join
and then casting from that to int
:
int main()
{
static int r1,r2;
void *result;
pthread_t t1, t2;
int i1[] = {1,2};
int i2[] = {3,4};
r1 = pthread_create( &t1, NULL, myfn, (void*)i1);
r2 = pthread_create( &t2, NULL, myfn, (void*)i2);
pthread_join( t1, &result );
r1 = (int)result;
pthread_join( t2, &result );
r2 = (int)result;
printf("Thread 1 returns: %d\n",r1);
printf("Thread 2 returns: %d\n",r2);
return 0;
}