Regarding Local Variable Passing in Thread

Regarding local variable passing in Thread

Each thread gets its own stack. The problem that you are facing has nothing to do with stack. The problem is the way it is generating code for your anonymous delegate. Use tool like refelector to understand the code that it is generating. The following will fix your problem:

static void Main() 
{
for (int i = 0; i < 10; i++)
{
int capture = i;
new Thread(() => Console.Write(capture)).Start();
}
}

Under the hood

Whenever you use a variable from outer scope (in your case variable i) in anonymous delegate, the compiler generates a new class that wraps anonymous function along with the data that it uses from the outer scope. So in your case the generated class contains - one function and data member to capture the value of variable i. The class definition looks something like:

class SomeClass
{
public int i { get; set; }

public void Write()
{
Console.WriteLine(i);
}
}

The compiler re-writes your code as follows:

SomeClass someObj = new SomeClass();
for (int i = 0; i < 10; i++)
{
someObj.i = i;
new Thread(someObj.Write).Start();
}

and hence the problem - that you are facing. When you capture a variable, the compiler does the following:

for (int i = 0; i < 10; i++)
{
SomeClass someObj = new SomeClass();
someObj.i = i;
new Thread(someObj.Write).Start();
}

Note the difference in SomeClass instantiation. When you capture a variable, it creates as many instances as there are number of iterations. If you do not capture a variable, it tries to use the same instance for all iterations.

Hope, the above explanation will clarify your doubt.

Thanks

passing a local variable to thread. is it possible?

This code is incorrect. The function aLocalFn may return before the thread function starts executing. And so by the time the thread function reads the local variable, the scope of that variable may have ended.

What can confuse matters is that this code may very well appear to work, at least some of the time. However, it is incorrect and you should use heap allocated memory instead.

C++ 11 - Is it safe when I pass a local variable as argument into a thread

std::thread will copy or move any argument you pass to it, so yes, it is thread safe.

Passing a raw pointer, on the other hand, is not thread-safe. In fact, passing a pointer to a local variable on a detached thread is doubly bad, because the thread is not guaranteed to complete before your local variable goes out of scope (you are not using .join() to block until thread is complete). Later on when the thread gets around to doing its work, it may or may not have something to work on, which can result in a crash.

http://en.cppreference.com/w/cpp/thread/thread/thread

The arguments to the thread function are moved or copied by value. If
a reference argument needs to be passed to the thread function, it has
to be wrapped (e.g. with std::ref or std::cref).

Also, if you do wrap a reference using std::ref, in general it becomes unsafe, because it can be accessed from the original context, so you're going to need to provide a synchronization method (mutex/lock, thread-safe container or what have you).

Is passing a reference to a local variable in main() to other threads/functions bad practice?

Your assumption

I am aware that passing references to local variables around should generally be avoided

seems unfounded.

There is nothing wrong with passing references to functions. However, a function that takes a reference to an object should not take ownership of that object. The function should not assume that the referenced object continues to live after it exits.

This is different from returning references to local variables, which is always wrong.

I see no problem (missing synchronization aside) with passing references to threads and this generally preferable to the alternative of using global variables.

Smart pointers, such as std::shared_ptr, are only required if the functions are supposed to take (shared) ownership of the object, e.g. if threadRun wants to keep a reference/pointer to the object after it exits.

how can I pass an local variable from a thread to another thread by accessing its memory address?

In your thread function, tid is the value of a particular member of the thread_args array in main. Any change to this variable is not reflected elsewhere.

Rather than dereferencing the converted argument right away, take it directly as a int *. Then you can do pointer arithmetic on it and further dereference it.

void* TaskCode(void* argument) {
int *tid = argument;
tid++;
*tid = *((int*)argument);
printf("\nI have the value: \" %d \" and address: %p! \n", *tid, (void *)tid);
return NULL;
}

Does local variable in thread function have separe copy according to thread?

These variables are allocated on the stack, and each thread has its own stack: these variables are private to each thread (they are not shared). (See this answer for more details.)

If you assign thread_data to a global pointer, for example, other threads will be able to access thread_data via the global pointer.

Thread specific data (e.g. pthread_setspecific) is used to create variables that are global, but still specific to each thread (not shared): They are thread-specific global variables.

You need to use thread specific variables when you want global variables, but don't want to share them between threads.



Related Topics



Leave a reply



Submit