पाठ 20 / 25
Threads, Mutexes and Atomics
Write basic concurrent code with jthread, mutexes, lock guards and atomics.
Doing several things at once safely
Since C++11, the standard library includes concurrency support. std::thread starts a new thread running a function; it must be joined or detached before destruction, or the program terminates. std::jthread (C++20) joins automatically in its destructor and supports cooperative cancellation through a std::stop_token, so prefer it. When threads share data and at least one writes, you need synchronisation, otherwise you have a data race, which is undefined behaviour. std::mutex with std::lock_guard or std::scoped_lock (RAII locks) protects critical sections; std::scoped_lock can lock several mutexes without deadlock. std::atomic<T> provides lock-free operations on simple values such as counters and flags. std::condition_variable lets threads wait for conditions. std::async and std::future run tasks and retrieve results. For parallel algorithms, C++17 added execution policies (std::execution::par) to many standard algorithms. Keep shared mutable state minimal; passing messages or giving each thread its own data avoids most bugs.
Counting safely from several threads
Atomic counter, mutex-protected vector and automatically joined threads.
#include <atomic>
#include <mutex>
#include <thread>
#include <vector>
int main() {
std::atomic<long long> hits{0};
std::vector<int> results;
std::mutex results_mutex;
{
std::vector<std::jthread> workers;
for (int t = 0; t < 4; ++t) {
workers.emplace_back([&, t] {
for (int i = 0; i < 100'000; ++i) {
hits.fetch_add(1, std::memory_order_relaxed); // atomic: no data race
}
std::scoped_lock lock(results_mutex); // RAII lock
results.push_back(t);
});
}
} // jthreads join automatically here
// hits == 400'000 and results holds 4 entries
}A shared whiteboard with a marker
A mutex is the single marker for a shared whiteboard: only the person holding it may write. An atomic counter is a tally clicker that everyone can press without clashing. Without either, people overwrite each other's work.
त्वरित जाँच: What happens if two threads modify the same int without synchronisation?
- The result is always correct
- The compiler adds a lock automatically
- One thread is blocked automatically
- It is a data race, which is undefined behaviour
Answer
It is a data race, which is undefined behaviour — Unsynchronised concurrent writes (or a write with a read) are data races and undefined behaviour.