Mustafa
Mustafa

Reputation: 101

Multithreading Output Confusion

Consider the following part in main

     tcount = 0;
     for (i=0; i<2; i++) {
      count[i] = 0;
      if (pthread_create(&tid[i], NULL, randint, (void *)&i) != 0) {
           exit(1);
      } else {
           printf("Created Thread %d\n", i);
      }
//        XXXXXXX
     }

     for (i=0; i<nthreads; i++) {
      printf("Waiting for thread %d to terminate\n", i);
      pthread_join(tid[i], NULL);
     }

and the randint code is:

void *randint(void *pint)
{
     int j, k;
     int rseed;

     j = *((int *)pint);
     printf("Started thread %d\n", j);
     while (tcount++ < NMAX) {
      count[j] += 1;
     }
     return(NULL);
}

The Output is:

Created Thread 0
Created Thread 1
Waiting for thread 0 to terminate
Started thread 0
Started thread 0
Waiting for thread 1 to terminate

I am confused why in the output there is:

Started thread 0
Started thread 0

I understand if it was:

Started thread 0
Started thread 1

Or:

Started thread 1
Started thread 1

But the 2 zeros is not clear !!! Any guess ???

Upvotes: 0

Views: 51

Answers (1)

Gray
Gray

Reputation: 116848

Your problem is here:

if (pthread_create(&tid[i], NULL, randint, (void *)&i) != 0) {

This is passing in the address of i when you should pass in its value. Typically we just pass in the integer as a void * as a hack.

if (pthread_create(&tid[i], NULL, randint, (void *)i) != 0) {
...
// in the thread we cast the void * back to an int (HACK)
j = (int)pnt;

The reason why i gets reset to 0 is that you are re-using i in the next loop:

for (i=0; i<nthreads; i++) {
  printf("Waiting for thread %d to terminate\n", i);
  pthread_join(tid[i], NULL);
}

But even if you used j in this loop here, you would not get Started thread 0 and then 1 because by the time the thread starts, the value of i has probably changed because the pthread_create(...) takes a relatively long time. If you used j in the second loop you would probably get:

Started thread 1
Started thread 1

Passing in i by value to the thread is the right thing to do here. If it needs to be an address then you should allocate space for a copy of it:

int *pnt = malloc(sizeof(i));
*pnt = i;
if (pthread_create(&tid[i], NULL, randint, (void *)pnt) != 0)
...
// remember to free it inside of the thread

Upvotes: 2

Related Questions