C++ 11 std :: thread :: detach和对共享数据的访问

Mat*_*gan 13 c++ multithreading c++11

如果在a std::thread和主线程(或任何其他线程)之间共享变量,即使thread::detach()在创建线程后立即执行该方法,您仍然可以访问这些共享变量吗?

Sea*_*ine 18

是! 调用后仍可访问全局变量,捕获变量和传入变量detach().

但是,如果您正在调用detach,则可能需要从创建该线程的函数返回,从而允许该线程对象超出范围.如果是这种情况,则必须注意该函数的所有本地都不是通过引用或通过指针传递给线程的.

您可以detach()将此视为一个声明,即该线程不需要创建线程的任何本地内容.

在下面的示例中,一个线程int在超出范围后继续访问起始线程的堆栈.这是未定义的行为!

void start_thread()
{
    int someInt = 5;
    std::thread t([&]() {
        while (true)
        {
            // Will print someInt (5) repeatedly until we return. Then,
            // undefined behavior!
            std::cout << someInt << std::endl;
        }
    });

    t.detach();
}
Run Code Online (Sandbox Code Playgroud)

这里有一些可能的方法可以防止地毯从你的线程中被扫除:

  • int在任何需要它的线程(可能是全局线程)的生命周期内声明不会超出范围的某个地方.
  • 将共享数据声明为a std::shared_ptr并将其按值传递到线程中.
  • 通过值(执行副本)传递到线程中.
  • 通过rvalue引用(执行移动)传递到线程中.


Dav*_*rtz 6

是.分离线程只是意味着它在完成后会自行清理,您不再需要,也不允许join它.