C++ 通过引用将参数传递给std::thread函数是否安全? #包括 #包括 #包括 #包括 使用名称空间std; 空f(常量向量和列) { 此线程::睡眠时间(1h); // //退出此函数前是否保证coll有效? // } int main() { { 向量coll(1024*1024*100); 螺纹(f,coll.detach(); } // //我知道std::thread默认情况下会将参数复制到自身中, //但我不知道这些复制的对象是否仍然有效 //销毁std::thread对象之后。 // 虽然(正确); }

C++ 通过引用将参数传递给std::thread函数是否安全? #包括 #包括 #包括 #包括 使用名称空间std; 空f(常量向量和列) { 此线程::睡眠时间(1h); // //退出此函数前是否保证coll有效? // } int main() { { 向量coll(1024*1024*100); 螺纹(f,coll.detach(); } // //我知道std::thread默认情况下会将参数复制到自身中, //但我不知道这些复制的对象是否仍然有效 //销毁std::thread对象之后。 // 虽然(正确); },c++,multithreading,c++11,standards,object-lifetime,C++,Multithreading,C++11,Standards,Object Lifetime,通过引用将参数传递到std::thread函数是否安全? 退出此功能之前,coll是否保证有效 更新:是。当您在main函数中将coll传递给std::thread的构造函数时,因为coll是一个对象,所以它将被复制。这个decaycopy本质上是moves向量(因此它变成右值),它将在线程执行期间绑定到f中的coll参数。(感谢@Praetorian的评论) 通过引用将参数传递到std::thread函数中是否安全 您的参数是decay复制的,因此您实际上从未通过引用std::threa

通过引用将参数传递到std::thread函数是否安全?
  • 退出此功能之前,
    coll
    是否保证有效

    • 更新:是。当您在
      main
      函数中将
      coll
      传递给
      std::thread
      的构造函数时,因为
      coll
      是一个对象,所以它将被复制。这个
      decay
      copy本质上是
      move
      s向量(因此它变成右值),它将在线程执行期间绑定到
      f
      中的
      coll
      参数。(感谢@Praetorian的评论)
  • 通过引用将参数传递到
    std::thread
    函数中是否安全

    • 您的参数是
      decay
      复制的,因此您实际上从未通过引用
      std::thread
      传递任何内容
  • std::decay的参考文件

  • 这个问题中的公认答案解释了传递给
    std::thread

正如@T.C.的评论,您没有将引用传递给线程,您只需在线程中复制一个向量:

#include <thread>
#include <string>
#include <vector>
#include <chrono>

using namespace std;

void f(const vector<string>& coll)
{
    this_thread::sleep_for(1h);

    //
    // Is coll guaranteed to be valid before exiting this function?
    //
}

int main()
{
    {
        vector<string> coll(1024 * 1024 * 100);
        thread(f, coll).detach();
    }

    //
    // I know std::thread will copy arguments into itself by default, 
    // but I don't know whether these copied objects are still valid
    // after the std::thread object has been destroyed.
    //

    while (true);
}
如果你真的想通过引用传递,你应该这样写:

thread(f, coll).detach(); // It's NOT pass by reference, but makes a copy.
如果线程试图访问向量,那么代码将出现段错误,因为当线程运行时,向量很可能已经被破坏(因为它超出了主程序的作用域)

关于你的问题:

通过引用将参数传递到
std::thread
函数中是否安全

  • 如果您确信对象在线程运行期间保持有效,那么它是安全的
  • 如果对象被破坏是不安全的,您将得到段错误

简短回答:是的,它是完全安全的,没有问题。您没有通过引用线程传递任何内容。很抱歉,您是正确的;我误读了代码。@T.C.,我知道默认情况下,
std::thread
会将参数复制到自身中,但是我不知道在
std::thread
对象被销毁后,这些复制的对象是否仍然有效。
std::thread
对象不再与执行线程关联,因为您将
从它分离。
线程
本身在调用
f
时将移动
向量
,该向量将绑定到
向量常量&
参数,其生存期将在
f
退出时结束,因此您的代码是安全的。您能否详细说明“
衰减
复制”的含义?如果未通过引用传递,则在何处/何时复制?在OP的示例中,显然必须将对副本的引用传递到
f
。也许还值得一提的是,lambdas仍然允许一个人通过引用进行捕获,而不会陷入这种腐朽的行为。对于新手来说,这是一个明确的答案。谢谢
thread(f, std::ref(coll)).detach(); // Use std::ref to pass by reference