std::future何时执行?

When does std::future get executed?

本文关键字:执行 future std 何时      更新时间:2023-10-16

创建启动策略设置为std::launch::async的线程时,cppreference上给出的描述为

启动一个新线程来异步执行任务

如果我有一个任意函数

double Foo(double i)
{
    return i * 5.0;
}

我设置了一个async呼叫,像这样

std::vector<double> values{5.0, 2.3, 7.1, 4.8, 1.5};
std::vector<std::future<double>> answers;
for (double value : values)
{
    answers.push_back(std::async(std::launch::async,
                                 Foo,
                                 value));
}

当我这样调用std::accumulate时:

double total = std::accumulate(begin(answers),
                               end(answers),
                               0.0,
                               [](double x, std::future<double>& t){return x + t.get();});

每个线程何时开始执行?它们一加入answers就开始了吗?或者他们等待直到他们的get被调用?如果是这样,我是否只是强迫它们顺序执行,因为它们的get是按照accumulate执行它们的顺序调用的?换句话说,我是否只是浪费时间设置这些未来,然后强制它们同步运行?

注意
函数Foo只是一些例子,我使用的实际函数做更多的工作。

实际上,它们是在创建future时启动的。它可能只被安排执行,或者可能在调用async返回之前被启动。

可能会尝试使用线程池等来一次只保持一定数量的线程运行(至少在最初),但这是一个实现质量问题,并且在不增加干扰或要求更多调用函数的情况下正确实现这一点是困难的。

标准并没有强制要求任何接近这个级别的行为,但在实践中,异步异步实际上是异步的。

一旦调用std::async,线程就会被启动。因此,您的线程将并发运行。

引用cpp-reference:

如果设置了异步标志(即策略&Std::launch::async != 0)然后async在一个新的执行线程上执行函数f初始化所有线程局部变量),就像由std::thread(f;Args…),除非函数f返回值或抛出异常时,它存储在共享状态中,可通过Std::future,异步返回给调用者。