我不明白std::thread
有一件事:
为什么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 */
}
的构造函数需要函数来运行rvalue?
我通常想要将一些成员的Functor运行到另一个线程。像这样:
std::thread
使用is
的当前实现我必须确保我的对象正在实现移动语义。我不明白为什么我不能通过引用传递它。
额外的问题是:通过rvalue引用函数意味着什么? Lambda表达式?
答案 0 :(得分:6)
在run_thread方法中,f
是一个自动变量。这意味着范围f
的底部将被销毁。你声称你将“等待线程完成”,但编译器/运行时系统不知道这一点!它必须假设f
将被删除,可能在应该调用其方法的线程有机会启动之前。
通过复制(或移动)f
,运行时系统可以控制其f
副本的生命周期,并且可以避免一些非常讨厌,难以调试的问题。
答案 1 :(得分:3)
std::reference_wrapper
会向被包装的对象公开operator()
。如果您愿意进行手动终身维护,std::thread t(std::ref(f));
将通过引用运行f
。
当然,在您的代码中,这会导致未定义的行为,因为您没有正确管理生命周期。
最后,请注意原始thread
是一个糟糕的“客户端代码”工具。 async
更好,但实际上您需要一个包含packaged_task
和future
s和条件变量的任务队列。 C ++ 11增加了足够的线程支持来编写一个不错的线程系统,但它提供了原语,而不是好的“客户端代码”工具。
在玩具程序中,这可能已经足够了。