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

时间:2017-01-05 03:32:15

标签: c++ multithreading c++11 standards object-lifetime

#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);
}

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

2 个答案:

答案 0 :(得分:4)

作为@ T.C.的评论,你没有传递对线程的引用,你只需在线程中复制一个向量:

-(IBAction) btnActions: (UIButton * ) sender {

  for (UIButton * b in self.btn) {
    //checking if already have borders for the buttons
    if (b.layer.cornerRadius == 13) {
      b.layer.borderWidth = 0;
      b.layer.cornerRadius = 0;
    }

    //setting the borders for the selected button
    if (b.tag == sender.tag) {
      b.layer.borderWidth = 2;
      b.layer.cornerRadius = 13;
      b.layer.borderColor = [UIColor yellowColor].CGColor;
    }
  }
}

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

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

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

那么你的问题是:

  

通过引用将参数传递给thread(f, std::ref(coll)).detach(); // Use std::ref to pass by reference 函数是否安全?

  • 如果您确定在线程运行期间对象仍然有效,则是安全的;
  • 如果物体被破坏是不安全的,你会得到段故障。

答案 1 :(得分:3)

  • 退出此功能前coll是否有效?

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

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

  • 此问题中接受的答案std::thread with movable, non-copyable argument解释了传递给std::thread的论据发生了什么