如何正确使用移动语义与对象中的运行线程?
样品:
#include <iostream>
#include <thread>
#include <vector>
struct A {
std::string v_;
std::thread t_;
void start() {
t_ = std::thread(&A::threadProc, this);
}
void threadProc() {
for(;;) {
std::cout << "foo-" << v_ << '\n';
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
};
int main() {
A m;
{
A a;
a.v_ = "bar";
a.start();
m = std::move(a);
}
std::cout << "v_ = " << m.v_ << '\n'; /* stdout is 'v_ = bar' as expected */
/* but v_ in thread proc was destroyed */
/* stdout in thread proc is 'foo-' */
m.t_.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望在移动后使用类成员,但是当我移出范围时,类成员被销毁并且std :: thread被移动到新对象中,但是它开始使用被销毁的成员.
在我看来,因为this在线程初始化中使用指针.
在这种情况下,最佳做法是什么?
正如所写,它不会起作用。移动后,线程m.t_指的是仍在运行的线程a.threadProc()。这将尝试打印a.v_.
片段甚至有两个问题:不仅被a.v_移出(因此它的值未指定),而且它也即将在另一个线程中被销毁,并且该销毁在使用后没有排序。
由于对象需要存活足够长的时间,并且由于线程而具有非平凡的生命周期,因此您需要将其从堆栈中取出并从向量中取出。相反,用于std::shared_ptr管理生命周期。您可能需要将它传递shared_ptr给线程,以避免在线程开始运行之前对象可能过期的竞争条件。你不能依赖std:shared_from_this.