扩展std :: thread的ref对象的传递范围

时间:2017-03-31 17:04:44

标签: c++ multithreading c++14

为了证明这个问题,让我提出一个简短的代码 -

void someMethod() {

  // CustomType obj;
  const auto obj = getCustomTypeObj();

  std::thread([](customType &obj) {
    // some delay
    obj.doSomething();
    obj.close();
    // can now be destructed
  }).detach();

  // similarly for std::async
  std::async(std::launch::async, [](customType &obj){
    obj.doSomething();
    obj.close();
  }

  // there might not be any use of obj here

  // should not be destructed here because std::thread might not get it.

}

在上面的代码中,构造了一个CustomType类型的对象,为其删除了复制构造函数。所以我必须在任何地方通过引用传递它,或者在相关范围内从头开始创建它。但是,对于我目前正在处理的1个场景,不太可能在std::thread执行方法内的相关范围内创建它。

我害怕的obj可能会在std::thread完成工作之前被破坏,然后我不知道会发生什么。那么我该如何解决将它的范围扩展到std :: thread' lambda的问题。

1 个答案:

答案 0 :(得分:3)

如果你的代码不正确,你没有传递你的对象,所以你的代码应该是:

  auto obj = getCustomTypeObj();

  std::thread([](customType &obj) {
    // some delay
    obj.doSomething();
    obj.close();
    // can now be destructed
  }, std::ref( obj ) ).detach();

为了避免对象生命周期问题,请将对象传递给lambda或按值运行,并将对象移动到那里:

  auto obj = getCustomTypeObj();

  std::thread([](customType arg) { // note by value, not reference
    // some delay
    arg.doSomething();
    arg.close();
    // arg will be destroyed here
  }, std::move( obj ) ).detach(); // object moved

现在lambda或function拥有该对象,它将在函数末尾被销毁。以下是live example,我只使用std::unique_ptr代替customType作为禁用复制以验证移动是否有效的类型。