pthred_exit return variable static vs global scope

85 views Asked by At

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 ?

1

There are 1 answers

0
caf On BEST ANSWER

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;
}