什么时候应该使用std :: async同步作为策略?

bal*_*lki 9 c++ asynchronous c++11

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

Mat*_* M. 5

Jagannath链接的非常有用的文章摘要,以及对可能用途的评论.

有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());
}
Run Code Online (Sandbox Code Playgroud)

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

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

  mc.lazy(f);
}
Run Code Online (Sandbox Code Playgroud)

请注意,这与使用(和闭包)略有不同std::function<int()>,因为计算一劳永逸地完成,保证后续的get调用始终返回相同的结果.

与其他策略的不同之处还可以表示当您不需要该值时是否执行操作.

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

因此,deferred为您提供更好的控制,这在呼叫有副作用时很重要.