views:

109

answers:

2

this might a simple query.

when we are creating a thread we are passing the (void *)t as an argument to a function PrintHello.we are copying the value in the pointer threadid(typacasting it to long) in tid which is a long variable again.i am confused with the parameter passing. is this a pass by reference or pass by value.over all is this correct? (value *)t. what value does it pass exactly?

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

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;

please help me to avoid my confusion:(

A: 

It should be pass by reference.

Make sure parameter u pass should either be global or dynamically allocated in order to access in thread function .

You r passing addresss so write this ....

rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&t);

Ashish
https://computing.llnl.gov/tutorials/pthreads/ shows this example.so is this example incorrect?
Vijay Sarathi
The example works correctly because the main thread does not stop before the childs - but this is an assumption which might not be true in more complex scenarios.It is just dangerous to simply copy and paste it in any situation...
weismat
the web page also says that `rc = pthread_create(` is an incorrect way of passing the arguments. but why?
Vijay Sarathi
The code posted by the OP does not do pass by reference, its pass by value.
Georg Fritzsche
Regarding John's question in the comment above, the pointer passed in is the address of a variable on the stack. If the function creating the thread finishes before the the thread the thread's data will nolonger be valid, and might well point to some new data on the stack (writing to this would corrupt the stack). This will only be safe if the function that creates the thread also waits for it to exit (joins with it).
iain
Regarding John's question on "computing.llnl.gov/tutorials/pthreads" the example is usually correct but would be considered bad style as it assumes the sizeof(long) <= sizeof(void *). Normally this is correct, however code like this is not portable. The bug that would result if sizeof(long) > sizeof(void *) would be very very difficult to track down and probably waste days or weeks for the brightest developers in a team. In short not worth it.
iain
To avoid bloating the code before you need to port to platforms where the assumption isn't valid one way is to put `STATIC_ASSERT(sizeof(long) <= sizeof(void*))` or similar where the assumption is made.
Georg Fritzsche
+5  A: 

What you are doing is pass by value. It is fine as long as sizeof(T) <= sizeof(void*) for the type T you are trying to pass.

If that is not the case, you should to create a T on the heap as it might be out of scope when the created thread tries to access it:

T* t = new T(someValue);
rc = pthread_create(&threads[t], NULL, PrintHello, (void*)t);
Georg Fritzsche
This is the correct answer. In this case, say you only want to pass 32/64-bit scalar variable, then it is safe. The value is just copied and you can read safely regardless the function terminates or not.
minjang