如果分离的std :: thread使用超出范围的对象,它是否安全?

时间:2015-10-22 08:46:54

标签: c++ multithreading c++11

想象一下,我启动了一个运行对象成员函数的std::thread。如果该对象在我创建线程的main函数中超出范围会发生什么?

class ThreadClass {
    public:
    ThreadClass(int i) : _a(i) {
    }

    void foo() {
        sleep(10);
        std::cout << "Is it safe here? " << _a << std::endl;
    }
    int _a;
};

int main() {
    {
        ThreadClass obj(3);
        std::thread t(&ThreadClass::foo, &obj);
        t.detach();
    }

    // Here obj goes out of scope
    // What about thread?

    sleep(20);
    return 0;
}

这是一个未定义的行为吗?

2 个答案:

答案 0 :(得分:5)

不,该代码不安全。 thread拥有对象的非拥有引用(通过指针&obj的副本)。一旦对象超出范围,那就是悬空参考。

答案 1 :(得分:3)

是的,这是未定义的行为。更具体地说,您将最终遇到分段错误,因为该线程正在尝试访问不再存在的某个对象。所以这就是我的建议:

  • 在任何线程的生命周期内声明obj不会超出范围的地方(可能是全局的)。
  • 传递值而不是引用。
  • 使用new创建对象,并使用std::shared_ptr将指针传递给线程。 (在这种情况下,您必须确保线程调用delete操作,以避免内存泄漏。