When a thread is created with the launch policy set as std::launch::async
, the description given on cppreference is
a new thread is launched to execute the task asynchronously
If I have some arbitrary function
double Foo(double i)
{
return i * 5.0;
}
And I set up an async
call like so
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));
}
When I call std::accumulate
like so:
double total = std::accumulate(begin(answers),
end(answers),
0.0,
[](double x, std::future<double>& t){return x + t.get();});
When do each of the threads kick off their execution? Did they start as soon as they were added to answers
? Or do they wait until their get
is invoked? If so, did I just force them to execute sequentially since their get
is called in the order that accumulate
executes them? In other words, did I just waste my time setting up these futures, then force them to run synchronously?
Note
The function Foo
was just some example, the actual function I'm using does more work.
The class template std::future provides a mechanism to access the result of asynchronous operations: An asynchronous operation (created via std::async, std::packaged_task, or std::promise) can provide a std::future object to the creator of that asynchronous operation.
A future is an object that can retrieve a value from some provider object or function, properly synchronizing this access if in different threads. "Valid" futures are future objects associated to a shared state, and are constructed by calling one of the following functions: async. promise::get_future.
3) std::future is not CopyConstructible.
Once you use the get() function on a future, it will wait until the result is available and return this result to you once it is. The get() function is then blocking. Since the lambda, is a void lambda, the returned future is of type std::future<void> and get() returns void as well.
Note that std::future references shared state that is not shared with any other asynchronous return objects (as opposed to std::shared_future ).
But if someone tries to reach this corresponding future value by using the get () function before it is available, then the get () function will block until the value is not found. std :: promise is also a class template and its object promises to set a value in the future.
Everything std :: promise has a corresponding object called std :: future, where others can claim the value set by the promise. Therefore, string 1 will create std ::promise object and download std :: future to it before transferring std ”” which promises string 2 i.e.
In practice, they are started when you create the future
. It may only be scheduled for execution, or might actually be kicked off before the call to async
returns.
There may be some attempt to keep only a certain number of threads running at a time (at least initially) with thread pooling etc, but that is a quality of implementation issue, and getting that right without being more intrusive or requiring more from the called function is hard.
The standard does not mandate anything close to that level of behavior, but in practice, async asyncs are actually async.
The threads will be kicked off as soon as you call std::async
. As such, your threads will run concurrently.
To quote cpp-reference:
If the async flag is set (i.e. policy & std::launch::async != 0), then async executes the function f on a new thread of execution (with all thread-locals initialized) as if spawned by std::thread(f, args...), except that if the function f returns a value or throws an exception, it is stored in the shared state accessible through the std::future that async returns to the caller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With