5

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

#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++ 文档中找不到关于这种使用模式的任何内容,我想确保它得到官方支持。

4

1 回答 1

0

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

  • future在对它执行 a 之前将其销毁时,它不会阻塞get。如果未来是使用创建的std::async,并且在它被销毁之前没有调用get它,那么它将一直阻塞直到结果可用。
    在此处查看更多信息:http: //en.cppreference.com/w/cpp/thread/future/~future

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

现在,如果Result该类持有非拥有内存(无论出于何种原因)或其他需要手动释放的资源怎么办。在这种情况下,您的代码的正确性就会受到质疑。更好的做法是将其分派到某个后台线程以执行缓慢移动的任务。

于 2016-05-31T06:59:10.473 回答