原始调用者被销毁后,std :: thread :: detach导致崩溃

时间:2013-08-30 19:22:48

标签: c++ multithreading c++11 detach stdthread

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()上的分离主题?

设计很糟糕。 如果正确生成/处理了调用者被销毁之前,如何在后台运行线程?

2 个答案:

答案 0 :(得分:12)

使线程成为类的成员,而不是在构造函数中将其分离,将其连接到析构函数中。要阻止线程循环,可以在类中包含一个布尔值,表示线程是否应该继续运行(std::atomic<bool> update)。

线程可以执行此操作:[this] { while (update) threadUpdate(); }

在班级的析构函数中,执行update = false,然后拨打thread.join()

答案 1 :(得分:7)

你无法阻止分离的线程。这就是.detach()的要点 - 至少就C ++标准而言,你没有任何方式来引用分离的线程。如果要保留线程的句柄,请存储std::thread并在析构函数中调用.join()