对以下异步行为感到困惑

时间:2018-03-21 15:54:01

标签: c++

我正在尝试找出以下代码,并且不确定std :: async部分正在做什么:

std::vector<double> RunParallel( std::vector<std::vector<int>> args)  
{
    std::vector<std::future<double>> results(args.size());
    for( int iter_job = 0;  iter_job < args.size(); ++iter_job )
    {
        int arg1 = args[iter_job][0];
        int arg2 = args[iter_job][1];
        results[iter_job]= std::async(std::launch::async, [&]
              { return (foo(arg1,arg2)); });
    }
    std::vector<double> returnValues;
    for(int iter_job =0; iter_job<args.size(); ++iter_job)
    {
          returnValues.push_back(results[iter_job].get());
    }
 }

我不明白std :: async调用中返回的内容。

不知怎的,这段代码会导致奇怪的结果,我想知道它是否与第一个for循环中间的返回调用有关。

2 个答案:

答案 0 :(得分:2)

[&]{ return (foo(arg1,arg2)); } lambda表达式,它生成一个不带参数的闭包并在调用时返回foo(arg1, arg2)

arg1arg2通过引用在闭包中捕获。这意味着只要for循环的迭代结束,闭包就会保持悬空引用。这可能是导致问题的原因。

按值捕获arg1arg2

[arg1, arg2]{ return foo(arg1, arg2); }

使用默认的&=抓取通常是一个坏主意,因为它们可能会引入微妙的错误。除非您有充分的理由不这样做,否则请更好地明确列出您的捕获。

答案 1 :(得分:1)

for循环中没有return - return位于您传递给async的函数中。

问题是该功能正在通过引用捕获arg1arg2,并且当它在将来某个时间被调用时,这些对象不再存在,因此尝试访问它们是未定义。

将捕获列表[&]替换为[arg1, arg2],以便按值捕获它们 (并输入一个空参数列表以获得良好的衡量标准:[arg1, arg2]() { ... }。)