Multithreading
Running code in parallel safely: threads, mutexes, condition variables, and deadlock avoidance
pthreads or Win32 threads.
- launch work on a
std::threadand manage its lifetime withjoin/detach- and prefer C++20std::jthread; - explain what a data race is and why it is undefined behaviour;
- protect shared state with
std::mutexand the RAII guardslock_guardandunique_lock; - coordinate threads with a
std::condition_variableusing the predicate-wait idiom; - recognise a deadlock and avoid it with lock ordering and
std::scoped_lock.
1. Concurrency vs. parallelism, and std::thread
Concurrency is a structuring property: several tasks are in progress over overlapping periods. Parallelism is an execution property: tasks literally run at the same instant on different cores. Threads let you express concurrency; whether it becomes real parallelism depends on the hardware. Use std::thread::hardware_concurrency() as a hint for how many cores are available.
A std::thread (from <thread>) starts running its callable immediately upon construction. You pass any callable - a function pointer, a lambda, a functor - plus its arguments. Arguments are copied into the thread by default; to pass by reference you must wrap them in std::ref.
#include <thread>
#include <iostream>
void greet(int id) { std::cout << "hello from " << id << "\n"; }
int main() {
std::thread t(greet, 42); // starts running now
t.join(); // wait for it to finish
}
Before a std::thread is destroyed you must decide its fate: join() blocks until the thread finishes, while detach() lets it run independently and severs your handle. If you destroy a joinable thread without doing either, the destructor calls std::terminate() and your program aborts. This harsh rule exists to stop you accidentally leaking a running thread.
std::jthread. A jthread ("joining thread") fixes the footgun: its destructor automatically joins, so forgetting to join no longer terminates the program. It also carries a std::stop_token so the thread can be asked to stop cooperatively. Prefer std::jthread in new C++20 code.