永远不要从 std::p ackaged_task 中检索 std::future 的结果是否安全?
Is it safe to never retrieve the result of a std::future from a std::packaged_task?
从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
类持有非拥有内存(无论出于何种原因)或其他需要手动释放的资源怎么办。在这种情况下,代码的正确性就值得怀疑了。更好的办法是将其调度到某个后台线程,用于缓慢移动的任务。
相关文章:
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 从返回 std::optional of std::vector 的函数中获取结果到调用方
- 如何将 std::将结果绑定到 std::function
- 为什么这个涉及 std::enable_if 的模板元函数会产生不希望的结果?
- 使用类似的比较函数时,在 c++ 中为 std:sort 获得不同的结果
- 使用std::tie进行类似golang的错误处理,同时返回结果,是否有缺点?(C++11)
- std::chrono::duration::count函数的实际结果类型是什么
- std::atomic_flag初始化结果
- 为什么 std::get<T> 其中 T 是调用 constexpr 函数失败的结果?
- 为什么一个表达式中的 std::string 连接给出的结果与逐个字符不同的结果?
- 相同的结果 qsort vs std::sort
- 为什么 std::locale( " " ).name() 在 clang 和 gcc 上给出不同的结果?
- 使用 std ::transform 构造 std::vector.返回未命名结果的可能性?
- std::reduce 似乎将结果转换为整数
- libc++ 对 std::map/set::equal_range 的实现给出了意想不到的结果
- 如何避免 std::abs 的意外结果?
- 为什么 std::when_any 使用 std::tuple 而不是 std::vector 作为其结果类型?
- std::vector 在 Linux 和 Windows 中给出了不同的结果
- 如何修改 std::generate 的绑定成员函数的结果