Asynchronous Programming in C++: Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Asynchronous Programming in C++: Complete Guide



Modern applications require high performance and responsiveness. Asynchronous programming in C++ allows you to perform long-running operations (I/O, network requests, complex computations) without blocking the main thread. In this guide, we will explore key C++ mechanisms for asynchronous work: from classic std::thread and std::async to modern C++20 coroutines. You will learn how to write efficient and safe asynchronous code.



1. Basics: std::thread and std::async



Let's start with the basic tools. std::thread creates a new thread of execution but requires manual management and synchronization. A more convenient option is std::async, which runs a function asynchronously and returns a std::future to retrieve the result.



#include <iostream>#include <future>#include <chrono>

int long_running_task(int input) { std::this_thread::sleep_for(std::chrono::seconds(2)); return input * 10;}

int main() { std::cout << "Starting asynchronous task..."; std::future<int> result = std::async(std::launch::async, long_running_task, 5); // Do something useful while the task is running std::cout << "Main thread continues working..."; // Get the result (blocks if the task is not yet complete) int value = result.get(); std::cout << "Result: " << value << std::endl; return 0;}


Key points:

  • std::launch::async — guarantees execution in a separate thread.
  • std::launch::deferred — defers execution until get() is called.
  • The get() method blocks the thread until the result is available.


2. Advanced Work: std::promise and std::future



When you need to pass a result from one thread to another, use the pair std::promise and std::future. The promise sets the value, and the future retrieves it. This is especially useful for thread pooling or task chains.



#include <iostream>#include <future>#include <thread>

void worker(std::promise<int> prom) { try { int result = 42; // Complex computations prom.set_value(result); } catch (...) { prom.set_exception(std::current_exception()); }}

int main() { std::promise<int> prom; std::future<int> fut = prom.get_future(); std::thread t(worker, std::move(prom)); // Get the result int value = fut.get(); std::cout << "Received value: " << value << std::endl; t.join(); return 0;}


Important features:

  • promise cannot be copied, only moved.
  • Exceptions are passed via set_exception.
  • future can only be used once (single retrieval).


3. C++20 Coroutines: Modern Approach



Coroutines are a powerful tool added in C++20. They allow suspending and resuming function execution without blocking the thread. This is ideal for asynchronous I/O operations and generators.



#include <iostream>#include <coroutine>#include <future>

struct SimpleTask { struct promise_type { SimpleTask get_return_object() { return {}; } std::suspend_never initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() { std::exit(1); } };};

SimpleTask async_operation() { std::cout << "Coroutine start";

Blogs

Book Recommendations