0
0
CppHow-ToBeginner · 3 min read

How to Use async in C++: Simple Guide with Examples

In C++, you use std::async to run functions asynchronously, which returns a std::future holding the result. You call std::async with a function and its arguments, then use future.get() to retrieve the result once ready.
📐

Syntax

The basic syntax of std::async is:

  • std::async(policy, function, args...)
  • policy is optional and controls how the task runs (e.g., std::launch::async to run asynchronously)
  • function is the callable to run
  • args... are the arguments passed to the function
  • The call returns a std::future<T> where T is the function's return type

You then call future.get() to get the result, which waits if the task is not done.

cpp
std::future<ReturnType> future = std::async(std::launch::async, function, args...);
ReturnType result = future.get();
💻

Example

This example shows how to run a function asynchronously that calculates the sum of two numbers. The main thread continues while the sum is computed in the background.

cpp
#include <iostream>
#include <future>

int add(int a, int b) {
    return a + b;
}

int main() {
    std::future<int> result = std::async(std::launch::async, add, 5, 7);
    std::cout << "Doing other work in main thread...\n";
    int sum = result.get();
    std::cout << "Sum is: " << sum << "\n";
    return 0;
}
Output
Doing other work in main thread... Sum is: 12
⚠️

Common Pitfalls

Common mistakes when using std::async include:

  • Not specifying std::launch::async may cause the function to run synchronously when future.get() is called.
  • Calling future.get() too early blocks the main thread, negating async benefits.
  • Ignoring exceptions thrown inside the async function, which are rethrown on future.get().

Always handle exceptions and choose the launch policy explicitly if you want true asynchronous behavior.

cpp
#include <iostream>
#include <future>
#include <stdexcept>

int fail() {
    throw std::runtime_error("Error in async task");
    return 0;
}

int main() {
    auto fut = std::async(std::launch::async, fail);
    try {
        fut.get(); // Will rethrow exception here
    } catch (const std::exception &e) {
        std::cout << "Caught exception: " << e.what() << '\n';
    }
    return 0;
}
Output
Caught exception: Error in async task
📊

Quick Reference

Tips for using std::async effectively:

  • Use std::launch::async to force asynchronous execution.
  • Store the returned std::future to get the result later.
  • Call future.get() once to retrieve the result and handle exceptions.
  • Remember that std::async can simplify threading without manual thread management.

Key Takeaways

Use std::async with std::launch::async to run functions asynchronously in C++.
std::async returns a std::future to access the result later with future.get().
Handle exceptions thrown inside async tasks by catching them when calling future.get().
Calling future.get() blocks until the async task finishes, so plan accordingly.
std::async simplifies running background tasks without manual thread management.