0

In this below link

https://computing.llnl.gov/tutorials/pthreads/samples/hello.c

in the statement rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); the coder has just passed a variable as 4th argument without passing address of that variable. Is this code correct? If yes how can we cast a variable to void *

The above link seems to be popular as it is listing first in Google for pthreads.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user1762571
  • 1,888
  • 7
  • 28
  • 47
  • 2
    Well, if `sizeof(t) <= sizeof(void *)`, then it's fine. And how? He **just** showed it: `void *p = (void *)other_expr;` –  Jul 11 '13 at 23:47
  • Pointers are integral types. – Kerrek SB Jul 11 '13 at 23:48
  • @user1762571 - please note the "related" questions on the right. There are several you might find helpful. – Duck Jul 12 '13 at 01:57

3 Answers3

1

Well it is a bit weird, but it does what it is supposed to.

The fourth argument is sent as argument to the PrintHello function/routine. It has to be passed as a void *.

Typically you have a pointer to a dynamically allocated object that you cast to void *. But here he defines a long t, casts it to void * (address) and sends it in. Then he casts it back to a long in PrintHello, so all is fine, but a bit ugly and could have gone "horribly" wrong if he would have cast it to a pointer and tried to access the memory it pointed to.

kamjagin
  • 3,614
  • 1
  • 22
  • 24
0

Yes this code is correct, if you don't try to access the memory pointed to by the parameter in the thread. Just convert it to a long in the thread.

tid = (long)threadid;

It converts the pointer to a long, but it doesn't touch the memory space that the pointer points to, which is most likely junk and will cause access violations.

For example if you did:

tid = (long)*threadid;

That would cause an access violation because you are trying to access the memory at the location pointed to by threadid.

If you would rather pass the pointer to a long integer you could do something like this.

...
long* pint = (long*)malloc(sizeof(long));
*pint = t;
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)pint);


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

But that requires the use of malloc and free

Keep in mind that a pointer is nothing more than a 32 or 64bit unsigned integer which represents a location in memory, you can put any number you want in a pointer, just don't try to access the memory it points to.

Hope that helps,

-Dave

0

Actually the 4th argument is the parameter to be passed to the thread, for example if there is a value that needs to be passed from the main thread to the newly created one, then this is done through this 4th argument. For example:

Lets say I have a thread being created from the main loop:

Int32 l_threadid = pthread_create(&l_updatethread,NULL,Thread,&l_filter);

As you can note that I'm passing the address of a value that is going to be used in the thread being created in the following way:

void* Thread(void *p_parameter)
{
   int *l_thread_filter = (int *)p_parameter;
   .... then play around with this variable ...
}
wrapperm
  • 1,266
  • 12
  • 18