std::future</* see below */> async( std::launch policy,
The function template std::async
runs the function f asynchronously (potentially in a separate thread which might be a part of a thread pool) and returns a std::future that will eventually hold the result of that function call.
Calls a function
fwith arguments
argsaccording to a specific launch policy
policy(see
below).
The return type of std::async
is std::future<V>, where V
is:
The call to std::async
synchronizes with the call to f, and the completion of f is sequenced before making the shared state ready.
std::future referring to the shared state created by this call to std::async
.
If the async flag is set, i.e. (policy & std::launch::async) != 0, then std::async
calls
as if in a new thread of execution represented by a std::thread object.
The calls of decay-copy are evaluated in the current thread.
(until C++23)The values produced by auto are materialized in the current thread.
(since C++23)If the function f returns a value or throws an exception, it is stored in the shared state accessible through the std::future that std::async
returns to the caller.
If the deferred flag is set (i.e. (policy & std::launch::deferred) != 0), then std::async
stores
Lazy evaluation is performed:
std::async
returned to the caller will evaluate INVOKE(std::move(g), std::move(xyz)) in the thread that called the waiting function (which does not have to be the thread that originally called std::async
), whereIf neither std::launch::async nor std::launch::deferred, nor any implementation-defined policy flag is set in policy, the behavior is undefined.
[edit] Policy selectionIf more than one flag is set, it is implementation-defined which policy is selected. For the default (both the std::launch::async and std::launch::deferred flags are set in policy), standard recommends (but does not require) utilizing available concurrency, and deferring any additional tasks.
If the std::launch::async policy is chosen,
std::async
call blocks until the associated thread has completed, as if joined, or else time out; andThrows
The implementation may extend the behavior of the first overload of std::async
by enabling additional (implementation-defined) bits in the default launch policy.
Examples of implementation-defined launch policies are the sync policy (execute immediately, within the std::async
call) and the task policy (similar to std::async
, but thread-locals are not cleared)
If the std::future obtained from std::async
is not moved from or bound to a reference, the destructor of the std::future will block at the end of the full expression until the asynchronous operation completes, essentially making code such as the following synchronous:
Note that the destructors of std::futures obtained by means other than a call to std::async
never block.
#include <algorithm> #include <future> #include <iostream> #include <mutex> #include <numeric> #include <string> #include <vector> std::mutex m; struct X { void foo(int i, const std::string& str) { std::lock_guard<std::mutex> lk(m); std::cout << str << ' ' << i << '\n'; } void bar(const std::string& str) { std::lock_guard<std::mutex> lk(m); std::cout << str << '\n'; } int operator()(int i) { std::lock_guard<std::mutex> lk(m); std::cout << i << '\n'; return i + 10; } }; template<typename RandomIt> int parallel_sum(RandomIt beg, RandomIt end) { auto len = end - beg; if (len < 1000) return std::accumulate(beg, end, 0); RandomIt mid = beg + len / 2; auto handle = std::async(std::launch::async, parallel_sum<RandomIt>, mid, end); int sum = parallel_sum(beg, mid); return sum + handle.get(); } int main() { std::vector<int> v(10000, 1); std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n'; X x; // Calls (&x)->foo(42, "Hello") with default policy: // may print "Hello 42" concurrently or defer execution auto a1 = std::async(&X::foo, &x, 42, "Hello"); // Calls x.bar("world!") with deferred policy // prints "world!" when a2.get() or a2.wait() is called auto a2 = std::async(std::launch::deferred, &X::bar, x, "world!"); // Calls X()(43); with async policy // prints "43" concurrently auto a3 = std::async(std::launch::async, X(), 43); a2.wait(); // prints "world!" std::cout << a3.get() << '\n'; // prints "53" } // if a1 is not done at this point, destructor of a1 prints "Hello 42" here
Possible output:
The sum is 10000 43 world! 53 Hello 42[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior LWG 2021 C++11 return type incorrect and value categorystd::async
might not throw std::bad_alloc if the
F
and the argument types
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4