【问题标题】:When should I use std::async with sync as policy?我什么时候应该使用带有同步的 std::async 作为策略?
【发布时间】:2012-02-12 20:46:01
【问题描述】:

std::async 有一个重载,它将 std::launch 策略作为第一个参数。我什么时候应该使用这个重载?有哪些不同的政策? (我认为同步和异步是两个选项)。我应该什么时候使用同步策略?这和直接运行有什么区别?

【问题讨论】:

标签: c++ asynchronous c++11


【解决方案1】:

来自the very helpful article that Jagannath linked 的总结,以及可能用途的 cmets。

有 3 种启动策略:

  • any: 库选择是否生成线程 a
  • async: 你明确要求产生一个线程
  • deferred:您明确要求生成线程

因此,deferred 策略是一种获得确定性惰性评估(也称为按需调用)的方法。例如,假设您有:

void MyClass::lazy(std::future<int> const& f) {
  if (this->notReady()) { return; }
  if (this->stillNotReady()) { return; }
  if (this->value() == 42) { return; }

  this->go(f.get());
}

现在,如果计算这个整数的值是long(例如,它可能会调用网络往返),那么在所有不需要它的情况下计算它有点浪费...现在我们有了这样做的工具!

void func(MyClass& mc) {
  std::future<int> f = std::async(std::launch::deferred, []() {
                         return stoi(memcached.get("KEY"));
                       });

  mc.lazy(f);
}

请注意,这与使用 std::function&lt;int()&gt;(和闭包)略有不同,因为计算是一劳永逸地完成的,保证后续调用get 总是返回相同的结果。

与其他策略的区别也可以用当你不需要该值时是否执行操作来表示

  • any:可能在另一个线程上执行(主动)或根本不执行
  • async: 将在另一个线程上执行
  • deferred:将不会执行

因此,deferred 为您提供更好的控制,如果调用有副作用,这一点很重要。

【讨论】:

  • “sync”其实是std::launch::deferred
  • @Cubbi:感谢您的指出,我应该与标准进行交叉检查。
  • “对get() 的后续调用”将调用未定义的行为,因为get() 使future 无效。你需要一个shared_future 来避免失效。
猜你喜欢
  • 2012-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多