table of contents
        
      
      
    | std::async(3) | C++ Standard Libary | std::async(3) | 
NAME¶
std::async - std::async
Synopsis¶
 Defined in header <future>
  
   template< class Function, class... Args >
  
   (since
  
   std::future<typename std::result_of<typename C++11)
  
   std::decay<Function>::type( (until
  
   typename std::decay<Args>::type...)>::type> C++17)
  
   async( Function&& f, Args&&... args );
  
   template< class Function, class... Args >
  
   (since
  
   std::future<std::invoke_result_t<std::decay_t<Function>, C++17)
  
   std::decay_t<Args>...>> (until
  
   C++20)
  
   async( Function&& f, Args&&... args );
  
   template< class Function, class... Args >
  
   [[nodiscard]] (since
  
   std::future<std::invoke_result_t<std::decay_t<Function>, C++20)
  
   std::decay_t<Args>...>>
  
   async( Function&& f, Args&&... args ); (1)
  
   template< class Function, class... Args >
  
   (since
  
   std::future<typename std::result_of<typename C++11)
  
   std::decay<Function>::type( (until
  
   typename std::decay<Args>::type...)>::type> C++17)
  
   async( std::launch policy, Function&& f, Args&&... args );
  
   template< class Function, class... Args >
  
   (since
  
   std::future<std::invoke_result_t<std::decay_t<Function>,
    (2) C++17)
  
   std::decay_t<Args>...>> (until
  
   C++20)
  
   async( std::launch policy, Function&& f, Args&&... args );
  
   template< class Function, class... Args >
  
   [[nodiscard]] (since
  
   std::future<std::invoke_result_t<std::decay_t<Function>, C++20)
  
   std::decay_t<Args>...>>
  
   async( std::launch policy, Function&& f, Args&&... args
  );
  
   The function template 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.
  
   1) Behaves as if (2) is called with policy being std::launch::async |
  
   std::launch::deferred.
  
   2) Calls a function f with arguments args according to a specific launch
    policy
  
   policy.
  
   * If the async flag is set (i.e. (policy & std::launch::async) != 0),
  
   then async executes the callable object f on a new thread of execution
  
   (with all thread-locals initialized) as if spawned by
  
   std::thread(std::forward<F>(f), std::forward<Args>(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 the deferred flag is set (i.e. (policy & std::launch::deferred) !=
  
   0), then async converts f and args... the same way as by std::thread
  
   constructor, but does not spawn a new thread of execution. Instead,
  
   lazy evaluation is performed: the first call to a non-timed wait
  
   function on the std::future that async returned to the caller will
  
   cause the copy of f to be invoked (as an rvalue) with the copies of
  
   args... (also passed as rvalues) in the current thread (which does not
  
   have to be the thread that originally called std::async). The result or
  
   exception is placed in the shared state associated with the future and
  
   only then it is made ready. All further accesses to the same
  
   std::future will return the result immediately.
  
   * If neither std::launch::async nor std::launch::deferred, nor any
  
   implementation-defined policy flag is set in policy, the behavior is
  
   undefined.
  
   If 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 doesn't require) utilizing available
  
   concurrency, and deferring any additional tasks.
  
   In any case, the call to std::async synchronizes-with (as defined in
  
   std::memory_order) the call to f, and the completion of f is sequenced-before
    making
  
   the shared state ready. If the async policy is chosen, the associated thread
  
   completion synchronizes-with the successful return from the first function
    that is
  
   waiting on the shared state, or with the return of the last function that
    releases
  
   the shared state, whichever comes first. If std::decay<Function>::type
    or each type
  
   in std::decay<Args>::type is not constructible from its corresponding
    argument, the
  
   program is ill-formed.
Parameters¶
 f - Callable object to call
  
   args... - parameters to pass to f
  
   bitmask value, where individual bits control the allowed methods of
  
   execution
  
   policy -
  
   Bit Explanation
  
   std::launch::async enable asynchronous evaluation
  
   std::launch::deferred enable lazy evaluation
Return value¶
std::future referring to the shared state created by this call to std::async.
Exceptions¶
 Throws std::system_error with error condition
  
   std::errc::resource_unavailable_try_again if the launch policy equals
  
   std::launch::async and the implementation is unable to start a new thread (if
    the
  
   policy is async|deferred or has additional bits set, it will fall back to
    deferred
  
   or the implementation-defined policies in this case), or std::bad_alloc if
    memory
  
   for the internal data structures could not be allocated.
Notes¶
 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 async call) and the task policy (similar to 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:
  
   std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f()
  
   std::async(std::launch::async, []{ g(); }); // does not start until f()
    completes
  
   (note that the destructors of std::futures obtained by means other than a
    call to
  
   std::async never block)
Example¶
// Run this code
  
   #include <iostream>
  
   #include <vector>
  
   #include <algorithm>
  
   #include <numeric>
  
   #include <future>
  
   #include <string>
  
   #include <mutex>
  
   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
  
   Defect reports
  
   The following behavior-changing defect reports were applied retroactively to
  
   previously published C++ standards.
  
   DR Applied to Behavior as published Correct behavior
  
   corrected return type
  
   LWG 2021 C++11 return type incorrect and value category and
  
   of arguments unclear in the deferred case clarified that rvalues
  
   are used
  
   the behavior was unclear if no standard the behavior is
  
   LWG 2120 C++11 or undefined
  
   implementation-defined policy is set
  
   Function and Args... were required to be
  
   LWG 3476 C++11 MoveConstructible requirements removed
  
   while no additional move constructions
  
   specified
See also¶
 future waits for a value that is set asynchronously
  
   (C++11) (class template)
| 2022.07.31 | http://cppreference.com |