为什么std :: thread需要函数来运行rvalue?

时间:2015-06-23 21:17:01

标签: c++ multithreading c++11

我不明白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表达式?

2 个答案:

答案 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_taskfuture s和条件变量的任务队列。 C ++ 11增加了足够的线程支持来编写一个不错的线程系统,但它提供了原语,而不是好的“客户端代码”工具。

在玩具程序中,这可能已经足够了。