繁体   English   中英

std::promise 和 std::future 的生命周期

[英]Lifetime of std::promise and std::future

我的代码:

void job_function(std::promise<void>& p) {
  do_it();
  p.set_value();
}

void foo() {

  std::promise<void> p;
  auto* thread = new std::thread(job_function, p);

  p.get_future().wait_for(std::chrono::seconds(1));

}

在这段代码中,如果 foo 的调用线程只等待 1 秒,直到未来完成。 等待结束后很可能会完成实际的工作。 在这种情况下, p 已经被破坏,所以调用 p.set_value 将不起作用。 我可以在堆上创建 p,但即使在这种情况下它也应该被删除,哪个线程应该删除 p 取决于作业完成和 wait_for 的顺序。 是否有可用于处理此问题的特定模式?

诀窍是将承诺移动到线程中,只保留未来。 另外,如果您不想等待线程,请将其分离。

void job_function(std::promise<void> p) {
  do_it();
  p.set_value();
}

void foo() {
  std::promise<void> p;
  std::future<void> f = p.get_future();
  std::thread thread(job_function, std::move(p));
  thread.detach();
  f.wait_for(std::chrono::seconds(1));
}

您正在重新实现std::packaged_task 您的代码可能是:

void job_function() {
  do_it();
}

void foo() {
  std::packaged_task<void(void)> task(job_function);
  std::future result = task.get_future();
  std::thread task_td(std::move(task));
  result.wait_for(std::chrono::seconds(1));
}

shared_ptr来救援

void job_function(std::shared_ptr<std::promise> p) {
  do_it();
  p->set_value();
}

void foo() {

  std::shared_ptr<std::promise> spPromise = std::make_shared<std::promise>();    
  
  auto* thread = new std::thread(job_function, spPromise);

  spPromise->get_future().wait_for(std::chrono::seconds(1));
}

现在,线程是在等待返回的原始函数之前还是之后完成都没有关系。 当 shared_ptr 的最后一个实例消失时,promise 对象被删除。

如果要保留通过引用传递语义,只需在线程的生命周期内保留按值捕获的 shared_ptr 即可。

void job_function(std::promise>& p) {
  do_it();
  p.set_value();
}

void foo() {

  std::shared_ptr<std::promise> spPromise = std::make_shared<std::promise>();    

  std::promise& p = *spPromise.get();

  auto* thread = new std::thread([spPromise] {
      job_function(*spPromise.get());  // same as job_function(p)
  });

  p.get_future().wait_for(std::chrono::seconds(1));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM