Threads
1 min read
Threads
C++11 added native threading support through <thread>, <mutex>, and related headers. Threads let multiple parts of a program run concurrently, making better use of multi-core hardware.
Creating a thread
#include <iostream>
#include <thread>
void worker(int id) {
std::cout << "Thread " << id << " running\n";
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join(); // wait for t1 to finish
t2.join(); // wait for t2 to finish
std::cout << "Both threads done\n";
}
std::thread takes a callable and any arguments to forward to it. Calling join() blocks until the thread finishes. If you destroy a std::thread without calling join() or detach(), std::terminate is called.
Lambdas as thread functions
#include <thread>
#include <iostream>
int main() {
int result = 0;
std::thread t([&result]() {
result = 42; // capture by reference
});
t.join();
std::cout << result << "\n"; // 42
}
Be careful with captures: the lambda must not outlive the captured variables.
Detaching threads
detach() lets a thread run independently. The thread keeps running after main returns — use carefully:
std::thread t(background_task);
t.detach(); // t is no longer joinable; runs independently
Detached threads are hard to reason about. Prefer join() and structured concurrency.
Hardware concurrency
unsigned int n = std::thread::hardware_concurrency();
std::cout << "CPU cores: " << n << "\n";
Thread IDs
std::cout << "Main thread: " << std::this_thread::get_id() << "\n";
std::thread t([]() {
std::cout << "Worker thread: " << std::this_thread::get_id() << "\n";
});
t.join();
Sleeping
#include <chrono>
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::this_thread::sleep_for(std::chrono::seconds(1));
A parallel sum example
#include <thread>
#include <vector>
#include <numeric>
#include <iostream>
int main() {
std::vector<int> data(1'000'000, 1);
long long result1 = 0, result2 = 0;
auto half = data.size() / 2;
std::thread t1([&]() {
result1 = std::accumulate(data.begin(), data.begin() + half, 0LL);
});
std::thread t2([&]() {
result2 = std::accumulate(data.begin() + half, data.end(), 0LL);
});
t1.join();
t2.join();
std::cout << result1 + result2 << "\n"; // 1000000
}
std::jthread (C++20)
std::jthread is a std::thread that automatically joins on destruction — eliminating the risk of accidental std::terminate:
#include <thread>
int main() {
std::jthread t([]() {
std::cout << "running\n";
});
} // t joins here automatically — no explicit join needed
Learn modern C++ through working code. Each chapter introduces one concept — variables, functions, classes, templates, smart pointers, concurrency — with a clear example, a line-by-line explanation, and notes on how it applies in real programs.
View book →