![](/img/trans.png)
[英]Non-obvious lifetime issue with std::promise and 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.