永远不要从 std::p ackaged_task 中检索 std::future 的结果是否安全?

Is it safe to never retrieve the result of a std::future from a std::packaged_task?

本文关键字:std 结果 future 结果是 是否 检索 安全 task ackaged 永远      更新时间:2023-10-16

std::packaged_task创建std::future是否安全,该在单独的线程上执行,但并不总是检索其结果?

#include <future>
#include <thread>
class Result {
Result() {}
~Result() {}
};
void foo() {
std::packaged_task<Result()> task(..);
auto future = task.get_future();
std::thread thread(std::move(task), ...);
thread.detach();
if (future.wait_for(std::chrono::milliseconds(timeout_ms)) == std::future_status::ready) {
auto result = future.get();  <--- Task didn't take too long, retrieve future result
...
}
}  <--- Task is taking too long, just abort and never call future.get()

它似乎适用于 Clang/libc++:~Result()std::packaged_task调用返回的结果,无论是否get()最终在std::future上调用,但由于我在C++文档中找不到有关此使用模式的任何内容,我想确保它得到官方支持。

这取决于....关于您认为对您的程序安全的内容。
对于您显示的上下文,它是安全的,如下所示:

  • 在对future进行get之前,当被破坏时,它不会阻塞。如果未来是使用std::async创建的,并且如果您在销毁之前不调用get,则在结果可用之前,它将阻塞。
    在此处查看更多相关信息: http://en.cppreference.com/w/cpp/thread/future/~future

这些操作不会阻止共享状态准备就绪, 除非如果满足以下所有条件,则可能会阻止:共享的 状态是通过调用 std::async 创建的,共享状态尚未 就绪,这是对共享状态的最后一次引用。

现在,如果Result类持有非拥有内存(无论出于何种原因)或其他需要手动释放的资源怎么办。在这种情况下,代码的正确性就值得怀疑了。更好的办法是将其调度到某个后台线程,用于缓慢移动的任务。