2

I want to run 4 different threads calling the same method, and I want to make sure that every single run comes from a different running thread.

With the code provided bellow, the method function is ran the expected number of times but it is always done by the same thread (the printed value does not change).

What should I change in the code to assure this condition? (which will result in this example in having 4 different values printed)

EDIT: same code but including an structure to see how the solution wil

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

struct object{
  int id;
};

void * function(void * data){

    printf("Im thread number %i\n",     data->id);
    pthread_exit(NULL);

}

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

    int i;
    int error;
    int status;
    int number_threads = 4;

    pthread_t thread[number_threads];

    struct object info;

    for (i = 0; i < number_threads; ++i){

        info.id = i;

        error = pthread_create(&thread[i], NULL, function, &info);

        if(error){return (-1);}
    }

    for(i = 0; i < number_threads; i++) {

        error = pthread_join(thread[i], (void **)&status);

        if(error){return (-1);}   
    }

}
qwerty
  • 486
  • 1
  • 11
  • 37
  • You seem to be passing the pointer to i and don't dereference otherwise you are printing the location? – MiltoxBeyond Apr 30 '15 at 22:14
  • With `struct`, it has precisely the same problem as before. Address of `info` is passed to all threads. You could use an array of structs: `struct info[4]` and pass different addresses with that. i.e. `&info[i]->id` to each thread with different values stored in each `id`. – P.P Apr 30 '15 at 23:17

3 Answers3

2

The reason you always see the same value

You are printing your pointer as a integer. data points to your variable i in your main. The address of i will not change, hence the same value being printed.

Printing the value of i

What you want to do is dereference data as a integer. The proper way to this is simple: *(int *)data. This means casting data a pointer to integer and then dereferencing to retrieve the value.


What should I change in the code to assure this condition? (which will result in this example in having 4 different values printed)

Printing the value of i will not guarantee that 4 different values will be printed.

  • It is totally plausible that the scheduler will not run your threads until all 4 are created and the main one is waiting to join(). Is that case, all threads would print 0.

  • It is possible that thread 1 and 2 reads i = 2 and 3 and 4 reads i = 3. Or some other combination of this.

How to be sure to print different values

To do this properly, you need to pass different parameters to each thread. The cleanest would be something like this.

int thread_number[4] = {0, 1, 2, 3};
// ...
error = pthread_create(&thread[i], NULL, function, &thread_number[i]);
Xaqq
  • 4,308
  • 2
  • 25
  • 38
1

Try modifying

printf("Im thread number %i\n", data);

to

printf("Im thread number %i\n", *((int *)data));
Arun
  • 19,750
  • 10
  • 51
  • 60
1

You are passing address of i to all 4 threads which is not what you want and it leads to race condition. If you simply want to pass the value of i and getting printed them by all threads then pass as:

error = pthread_create(&thread[i], NULL, function, (void *)i);

and change the print line to:

printf("Im thread number %i\n", (int)data);
P.P
  • 117,907
  • 20
  • 175
  • 238