13

我面临一种情况,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;
}

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

4

2 回答 2

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方法将正常工作。否则,跟着移动的未来走,它更干净......

于 2014-08-25T09:49:26.053 回答
2
future<void> MyClass::MyAsyncFunc() {
  std::future<void> f = std::async(...
  return f;
} //future out of scope, will block

and

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

    return shared_ftr;
}

are equivalent. The later will work exactly when the former will.

The future in the function that goes out of scope is moved from and therefore can't block. The blocking most likely happens in the calling function, which you have not shown.

于 2014-08-25T09:55:42.633 回答