Reputation: 1043
I'm trying to figure out following code and am not sure what the std::async part is doing:
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());
}
}
I don't understand what the return is doing in the std::async call.
Somehow this code is leading to strange results and I wonder if it has to do with the return call in the middle of the first for loop.
Upvotes: 1
Views: 34
Reputation: 66371
There's no return
in the for loop - the return
is in the function that you're passing to async
.
The problem is that the function is capturing arg1
and arg2
by reference, and when it's called some time in the future those objects no longer exist, so attempting to access them is undefined.
Replace the capture list [&]
with [arg1, arg2]
to capture them by value instead.
(And throw in an empty parameter list for good measure: [arg1, arg2]() { ... }
.)
Upvotes: 1
Reputation: 93264
[&]{ return (foo(arg1,arg2)); }
is a lambda expression that produces a closure taking no arguments and returning foo(arg1, arg2)
upon invocation.
arg1
and arg2
are captured by reference in the closure. This means that as soon as an iteration of the for
loop ends, the closure will hold dangling references. This is likely the cause of your problem.
Capture arg1
and arg2
by value instead:
[arg1, arg2]{ return foo(arg1, arg2); }
Using the default &
or =
captures is usually a bad idea as they can introduce subtle bugs. Prefer listing your captures explicitly unless you have a good reason to not do so.
Upvotes: 2