当我访问它时,这个异步技巧会起作用还是状态会悬空?

时间:2014-08-25 07:54:07

标签: c++ multithreading c++11 asynchronous dangling-pointer

我面临的情况是完全异步启动std::async操作会很好。

future<void> MyClass::MyAsyncFunc() {
    std::future<void> f = std::async(...);
    return f;
}  // The future goes out of scope, will block.

问题是,如果我不保存未来,该功能将在最后阻止。我希望这不会发生。

这会阻止std::future在函数范围的末尾调用它的析构函数:

shared_ptr<future<void>> MyClass::MyAsyncFunc() {
    auto shared_ftr = std::make_shared<std::future<void>>();
    *shared_ftr = std::async([shared_ftr]() {...});
    return shared_ftr;
}

这可能有用吗?当我不将结果保存在变量中时会发生什么?

2 个答案:

答案 0 :(得分:6)

这是一个完全成熟的例子。这种模式确实有效,我在boost asio和异步操作中广泛使用它。

#include <chrono>
#include <iostream>
#include <future>
#include <memory>
#include <thread>

std::shared_ptr<std::future<int>> get_task()
// std::future<int> get_task() // rely on move, future supports move
{
  auto f = std::make_shared<std::future<int>>();
  //std::future<int> f = std::async(std::launch::async, [] {
  *f = std::async(std::launch::async, [f] {
    (void) f;
    std::cout << "calculating" << std::endl;
    for (int x = 0; x < 10; ++x)
      std::this_thread::sleep_for( std::chrono::milliseconds( 200 ) );
    std::cout << "done." << std::endl;
    return 100;
  });

  return f;
}


int main(void)
{
  std::cout << "getting task" << std::endl;
  //auto f = get_task(); <-- the future is moved not copied, so there is no block here
  get_task();
  std::cout << "waiting" << std::endl;
//  f.wait(); <-- now wait for it to complete...
//  std::cout << " got: " << f.get() << std::endl;
  // Wait for the truly async task to complete...
  std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}

我要表达的唯一问题是在最后等待,而不是捕获future(无论是移动还是通过shared_ptr),你无法阻止应用程序终止之前任务完成......

如果您有其他方法可以确保延续,那么shared_ptr方法可以正常工作。另外,与移动的未来一起走,它更干净......

答案 1 :(得分:2)

future<void> MyClass::MyAsyncFunc() {
  std::future<void> f = std::async(...
  return f;
} //future out of scope, will block

shared_ptr<future<void>> MyClass::MyAsyncFunc() {
    auto shared_ftr = std::make_shared<std::future<void>>();
    *shared_ftr = std::async([]() {...});

    return shared_ftr;
}

等效。后者将完全适用于前者。

超出范围的函数的未来将被移除,因此无法阻止。阻止最有可能发生在您未显示的调用函数中。