c++pthreadspthread-join

Threads appear to run randomly.. Reliable only after slowing down the join after thread creation


I am observing strange behavior using pthreads. Note the following code -

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <pthread.h>
#include <unistd.h>


typedef struct _FOO_{
  int ii=0;
  std::string x="DEFAULT";
}foo;


void *dump(void *x)
{
  foo *X;
  X = (foo *)x;
  std::cout << X->x << std::endl;
  X->ii+=1;
}



int main(int argc, char **argv)
{

  foo X[2];
  const char *U[2] = {"Hello", "World"}; 
 
  pthread_t t_id[2];
  int t_status[2];

  /*initalize data structures*/
  for(int ii=0; ii < 2; ii+=1){
    X[ii].x=U[ii];
  }
  

  foo *p = X;
  for(int ii=0; ii < 2; ii+=1){
    t_status[ii] = pthread_create(&t_id[ii], NULL, dump, (void *)p);
    std::cout << "Thread ID = " << t_id[ii] << " Status = " << t_status[ii] << std::endl;
    p+=1;
  }

  //sleep(1);    /*if this is left commented out, one of the threads do not execute*/
  
  for(int ii=0; ii < 2; ii+=1){
    std::cout << pthread_join(t_status[ii], NULL) << std::endl;
  }

 
  for(int ii=0; ii < 2; ii+=1){
    std::cout << X[ii].ii << std::endl;
  }
  
}

When I leave the sleep(1) (between thread create and join) call commented out, I get erratic behavior in the randomly only 1 of the 2 thread run.

rajatkmitra@butterfly:~/mpi/tmp$ ./foo
Thread ID = 139646898239232 Status = 0
Hello
Thread ID = 139646889846528 Status = 0
3
3
1
0

When I uncomment sleep(1). Both threads execute reliably.

rajatkmitra@butterfly:~/mpi/tmp$ ./foo
Thread ID = 140072074356480 Status = 0
Hello
Thread ID = 140072065963776 Status = 0
World
3
3
1
1

The pthread_join() should hold up exit from the program, till both threads complete, but in this example I am unable to get that to happen without the sleep() function. I really do not like the implementation with sleep(). Can someone tell me if I am missing something??


Solution

  • See Peter's note -

    pthread_join should be called with the thread id, not the status value that pthread_create returned. So: pthread_join(t_id[ii], NULL), not pthread_join(t_status[ii], NULL). Even better, since the question is tagged C++, use std::thread. – Pete Becker