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

xml*_*lmx 15 c++ standards multithreading object-lifetime c++11

#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);
}
Run Code Online (Sandbox Code Playgroud)

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

Min*_*ine 5

正如@TC 的评论,您没有传递对线程的引用,您只需在线程中复制向量:

thread(f, coll).detach(); // It's NOT pass by reference, but makes a copy.
Run Code Online (Sandbox Code Playgroud)

如果你真的想通过引用传递,你应该这样写:

thread(f, std::ref(coll)).detach(); // Use std::ref to pass by reference
Run Code Online (Sandbox Code Playgroud)

然后,如果线程尝试访问向量,代码将出现段错误,因为当线程运行时,向量很可能已经被破坏(因为它在主程序中超出了它的范围)。

所以你的问题:

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

  • 如果您确定对象在线程运行期间保持有效,则是安全的;
  • 如果对象被破坏,这是不安全的,你会得到段错误。


vol*_*var 3

  • 退出这个函数之前保证coll有效吗?

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

    • 您的参数被decay复制,因此您实际上从未通过引用传递任何内容std::thread
  • 参考std::decay: http: //www.cplusplus.com/reference/type_traits/decay/

  • 这个问题std::thread with moving, non-copyable argument中接受的答案解释了传递给的参数会发生什么std::thread

  • 你能详细说明一下“腐烂复制”是什么意思吗?如果不是通过引用传递,那么副本是在哪里/何时制作的?显然,对副本的引用必须传递到 OP 示例中的“f”中。还值得注意的是,lambda 仍然允许通过引用进行捕获,而不会遇到这种衰退行为。 (3认同)