tags:

views:

106

answers:

2

I have just started learning pthreads API and I am following the tutorial here

However, in an example program of pthread_create, the sample program creates a long variable and passes its value, typecasted as void*. In the thread entry function, it dereferences it just like a long.

Is this legit? I understand if I pass the address of variable t, every thread would be acting on the same variable and not on a copy of it. Can we do this because it's a void* and the compiler has no idea about what type we are sending?

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

#define NUM_THREADS     5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }
   pthread_exit(NULL);
}
+4  A: 

It's as legitimate as any kind of typecasting. The point is that nothing can be done with the value the argument points to, until it is typecast, hence tid = (long)threadid.

Check the older Q&A When to use a void pointer?.

Charles Stewart
You're saying, `void*` means "pointer to something", but that "something" needs to be defined before it can be used, right?
Abel
@Abel: right. The point is when you want to do something with a pointer that can't be given the type information.
Charles Stewart
+4  A: 

This works as long as sizeof(long) <= sizeof(void*), and that every value of long can be represented as a void*.

Better would be to pass the address of the variable. You can cast from a T* to void*, and back again safely and without assumption.

GMan
@Charles `sizeof(void)` and `sizeof(void*)` are different beasts
qrdl
@qrdl: Right you are!
Charles Stewart