user1762571
user1762571

Reputation: 1949

Understanding pthread_ create arguments in C

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.

Upvotes: 0

Views: 124

Answers (3)

wrapperm
wrapperm

Reputation: 1296

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 ...
}

Upvotes: 0

user2527098
user2527098

Reputation:

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

Upvotes: 0

kamjagin
kamjagin

Reputation: 3654

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.

Upvotes: 1

Related Questions