Concurrency Basics

Concurrency Basics

Start threads safely, protect shared data, and avoid common synchronization mistakes.

Concurrency Basics

Launch a thread

std::thread worker([] {
    do_work();
});
worker.join();

Protect data

std::mutex m;
int total = 0;

void add() {
    std::lock_guard<std::mutex> lock(m);
    ++total;
}

What to avoid

Practical rule

Make correctness obvious first. Parallel speedups matter only after the sequential design is correct.

Prefer std::jthread for owned worker threads

std::jthread worker([](std::stop_token stop) {
    while (!stop.stop_requested()) {
        poll_once();
    }
});

std::jthread joins on destruction and supports cooperative cancellation through std::stop_token.

Condition variables and predicates

Always wait with a predicate so spurious wakeups do not break correctness.

cv.wait(lock, [] { return ready; });

When atomics are appropriate

Use atomics for small shared states such as counters, flags, and state transitions. Reach for mutexes when you need to protect larger invariants.