Reputation: 4369
There is one thing about std::thread
which I don't understand:
why the constructor of std::thread
takes function to run by rvalue?
I usually want to run a Functor with some members to another thread. Like this:
struct Function
{
void operator() ( /* some args */)
{
/* some code */
}
/* some members */
}
void run_thread()
{
Functor f( /* some data */);
std::thread thread(f, /* some data */);
/* do something and wait for thread to finish */
}
With current implementation of std::thread
I must be sure my object is implementing move semantics. I don't get why cannot I pass it by reference.
Extra question is: what does it mean to refer to function by rvalue? Lambda expression?
Upvotes: 6
Views: 915
Reputation: 275936
std::reference_wrapper
will expose an operator()
to the wrapped object. If you are willing to do the manual lifetime maintenance, std::thread t(std::ref(f));
will run f
by reference.
Of course in your code, this induces undefined behaviour as you did not manage lifetimes properly.
Finally, note that raw thread
is a poor "client code" tool. async
is a touch better, but really you want a task queue with packaged_task
s and future
s and condition variables. C++11 added enough threading support to write a decent threading system, but it provides primitives, not good "client code" tools.
In a toy program it may be enough.
Upvotes: 3
Reputation: 9434
In your run_thread method f
is an auto variable. That means at the bottom of the scope f
will be destroyed. You claim that you will "wait for the thread to finish" but the compiler/runtime system does not know that! It has to assume that f
will be deleted, possibly before the thread that is supposed to call its method has a chance to start.
By copying (or moving) the f
, the run time system gains control of the lifetime of its copy of f
and can avoid some really nasty, hard to debug problems.
Upvotes: 6