如何通过线程将值异步映射到函数上?

Hoo*_*ked 3 c++ multithreading asynchronous c++11

我正在尝试学习如何在C ++ 11中执行“令人尴尬的”并行任务。我遇到的一个常见模式是在一个值范围内求值时获得函数的结果,类似于调用python的multiprocessing.Pool.map。我编写了一个最小的示例,显示了我知道该怎么做,即调用单个进程并等待结果。如何异步“映射”此调用并等待所有值完成?理想情况下,我希望结果的长度和顺序与原始向量相同。

#include <iostream>
#include <thread>
#include <future>
#include <vector>

using namespace std;

double square_add(double x, double y) { return x*x+y; }

int main() {
  vector<double> A = {1,2,3,4,5};

  // Single evaluation
  auto single_result = std::async(square_add,A[2],3);
  cout << "Evaluating a single index " << single_result.get() << endl;

  // Blocking map
  for(auto &x:A) {
    auto blocking_result = std::async(square_add,x,3);
    cout << "Evaluating a single index " << blocking_result.get() << endl;
  }

  // Non-blocking map?

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

注意:要使此代码与gcc我编译需要-pthreads标志。

bst*_*our 5

std :: async返回将来,因此您可以将它们存储在向量中以备后用:

std::vector<std::future<double>> future_doubles;
future_doubles.reserve(A.size());
for (auto& x : A) {
    // Might block, but also might not.
    future_doubles.push_back(std::async(square_add, x, 3));
}

// Now block on all of them one at a time.
for (auto& f_d : future_doubles) {
    std::cout << f_d.get() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

现在,上面的代码可能会或可能不会异步运行。由实现/系统决定异步执行任务是否值得。如果要强制其在单独的线程中运行,则可以将可选的launch_policy传递给std :: async,将调用更改为

future_doubles.push_back(std::async(std::launch::async, square_add, x, 3));
Run Code Online (Sandbox Code Playgroud)

有关更多信息std::async和各种政策,请参见此处