Does async always use another thread/core/process in C++?

As I know async executes a function in another thread/process/core and don't block main thread, but does it happens always?

std::async is guaranteed to execute on a separate thread only if std::launch::async is passed as the first argument:

  • std::launch::async: a new thread is launched to execute the task asynchronously
  • std::launch::deferred the task is executed on the calling thread the first time its result is requested (lazy evaluation)

The default launch policy is std::launch::async | std::launch::deferred.


std::async returns std::future. std::future's destructor will block only if the future was returned from std::async:

these actions will not block for the shared state to become ready, except that it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state


  • In your first code snippet, you create an rvalue expression which is immediately destroyed - therefore "async" will be printed before "main".

    1. Async anonymous function is created and starts executing.

    2. Async anonymous function is destroyed.

      • main execution is blocked until the function is completed.

      • "async" is printed.

    3. main execuction resumes.

      • "main" is printed.

  • In your second code snippet, you create an lvalue expression whose lifetime is bound to the variable f. f will be destroyed at the end of the main function's scope - therefore "main" will be printed before "async" due to the Delay(1000).

    1. Async anonymous function is created and starts executing.

      • There's a Delay(1000) that delays "async" from being printed immediately.
    2. main execution continues.

      • "main" is printed.
    3. End of main's scope.

    4. Async anonymous function is destroyed.

      • main execution is blocked until the function is completed.

      • "async" is printed.


It prints async main, so does that mean that the main thread waits until async finishes?

Yes it does, but that is because you do not capture the returned future from async. async is special in that the future returned from it blocks in the destructor until the thread completes. Since you do not capture the returned future

async(launch::async,[]()
{
    Sleep(1000);
    puts("async");
});

must finish before progress is made in the current thread as that returned future is destroyed at the end of the expression.

It prints main async. This makes it seem like main doesn't wait for async to finish.

Which is what you really want when you call async. Since you have captured the future your main thread is allowed to continue on while the asynchronis task is completed. Since you have a delay in that thread main is going to print before the thread.