C++ Tutorial · Advanced C++ · Lesson 20 of 21

C++ Threads

std::thread, std::jthread, mutexes and std::async.

Concurrency in the standard library

  • std::jthread (C++20) runs a function on a new thread and joins automatically.
  • std::mutex with std::lock_guard protects shared data.
  • std::atomic<int> gives lock-free counters.
  • std::async runs a task and returns a std::future for the result.
Example 1
#include <atomic>
#include <future>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>

int main() {
    std::atomic<int> counter{0};
    std::mutex m;
    std::vector<int> log;
    {
        std::vector<std::jthread> workers;
        for (int id = 0; id < 4; ++id) {
            workers.emplace_back([&, id] {
                for (int i = 0; i < 1000; ++i) counter++;
                std::lock_guard lock(m);
                log.push_back(id);
            });
        }
    }   // jthreads join here
    std::cout << "counter: " << counter << ", workers finished: " << log.size() << '\n';

    auto future = std::async(std::launch::async, [] { return 6 * 7; });
    std::cout << "async result: " << future.get() << '\n';
}

Output

counter: 4000, workers finished: 4
async result: 42

Run this on your computer — see “Get Started” for setup.

Compile with -pthread on Linux if your toolchain needs it.

Test yourself

What does std::jthread do that std::thread doesn't?

  1. Runs faster
  2. Joins automatically when destroyed
  3. Uses green threads
  4. Prevents data races
Show answer

Answer: Joins automatically when destroyed