A quote from Nikolai Josuttis - Standard Library C++11:
Detached threads can easily become a problem if they use nonlocal resources. The problem is that you lose control of a detached thread and have no easy way to find out whether and how long it runs. Thus, make sure that a detached thread does not access any objects after their lifetime has ended. For this reason, passing variables and objects to a thread by reference is always a risk. Passing arguments by value is strongly recommended.
So further the author explains, that even if you pass a reference as a function argument to a thread, it still passes by value, so you must indicate the reference with std::ref
.
I have these questions, see the code below:
void f(std::vector<int> V){...}
void g(std::vector<int>& V){...}
std::vector<int> V;
std::thread t1(f, V);
std::thread t2(f, std::ref(V));
std::thread t3(g, V);
std::thread t4(g, std::ref(V));
What are the differences in these 4 lines? Which lines are equivalent?
I am not joining or detaching thread, it's not about that, it's about the ways of passing the function argument.
If you have used std::thread or std::bind , you probably noticed that even if you pass a reference as parameter, it still creates a copy instead. From cppreference, The arguments to the thread function are moved or copied by value.
You can only pass a single argument to the function that you are calling in the new thread.
In c++11 to pass a referenceto a thread, we have std::ref(). std::thread t3(fun3, std::ref(x)); In this statement we are passing reference of x to thread t3 because fun3() takes int reference as a parameter. If we try to pass 'x' or '&x' it will throw a compile time error.
std::thread Threads allow multiple functions to execute concurrently. std::thread objects may also be in the state that does not represent any thread (after default construction, move from, detach, or join), and a thread of execution may not be associated with any thread objects (after detach).
t1
:This simply passes a copy of V
to the thread.
t2
:Similarly to t1
, a copy of V
is passed to the thread, but the actual copy is made in the called thread instead of the caller thread. This is an important distinction because should V
be altered or cease to exist by the time the thread begins, you will end up with either a different vector or Undefined Behavior.
t3
:This should fail to compile as the thread will move the vector into the LValue reference, which is supposed to be illegal.
t4
:This passes the vector by reference to the thread. Any modifications to the passed reference will be applied to V
, provided that proper synchronisation is performed, of course.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With