簡體   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