struct Test {
bool active{true};
void threadedUpdate() {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if(!active) // crashes here after Test instance is destroyed
return;
}
Test() {
std::thread([this]{ while(true) threadedUpdate(); }).detach();
}
~Test() {
// somehow stop the detached thread?
}
};
初始化Test
的实例时,它会生成并分离在后台运行的std::thread
。当同一个实例被销毁时,前面提到的线程会尝试访问active
成员,该成员与实例一起被销毁,导致崩溃(以及 AddressSanitizer 回溯)。
有没有办法停止 ~Test()
上的分离主题?
设计很糟糕。 如果正确生成/处理了调用者被销毁之前,如何在后台运行线程?
答案 0 :(得分:12)
使线程成为类的成员,而不是在构造函数中将其分离,将其连接到析构函数中。要阻止线程循环,可以在类中包含一个布尔值,表示线程是否应该继续运行(std::atomic<bool> update
)。
线程可以执行此操作:[this] { while (update) threadUpdate(); }
。
在班级的析构函数中,执行update = false
,然后拨打thread.join()
答案 1 :(得分:7)
你无法阻止分离的线程。这就是.detach()
的要点 - 至少就C ++标准而言,你没有任何方式来引用分离的线程。如果要保留线程的句柄,请存储std::thread
并在析构函数中调用.join()
。