Runnable companions to the book.
Every claim made in the book has a demo behind it. Each demo
is a self-contained Docker project with its own
./demo.sh and its own Containerfile(s). Read the
matching chapter for context, then run the demo from its
directory.
Runnable examples
Runnable companions to the book. Each one makes a single pattern concrete and runnable with one command. Each card links to the demo's page on this site (a rendering of the README with cross-references), and each page links to the source on GitHub. Each demo also stands alone — run it without reading the book first if you'd rather poke at it directly.
Four Execution Models
Counts distinct CPUs touched, peak in-flight tasks, and interleaves across sequential, concurrent-pinned, parallel, and oversubscribed models — proof by observable, not by stopwatch.
Cache Hierarchy Latency
A single-threaded pointer-chase walks a random permutation at five working-set sizes from 8 KiB to 256 MiB. Latency rises monotonically as each step outgrows the next cache level.
Deadline Propagation
A four-hop call chain shares one steady_clock deadline end to end. Injecting a slow hop anywhere in the chain still keeps the total wall-clock budget, and a hop entered past its deadline does no work at all.
Clean jthread Shutdown
SIGTERM sets a lock-free flag; the main thread then calls request_stop() and join() on every worker itself, since request_stop() isn't signal-safe. A Lua harness sends a real SIGTERM and asserts exit 0 inside the grace period, with no forced kill.
Futex Cost Under Contention
Baseline, uncontended, and contended modes run the identical counter increments. When strace is available, futex counts show the contended case crossing into the kernel far more often than the uncontended one, which should match the no-lock baseline.
Lock Ordering & Deadlock
A std::latch forces two threads into a textbook AB/BA deadlock under lock_guard on every single run. The identical opposite-order acquisition under std::scoped_lock always completes, because its internal algorithm doesn't care what order its own arguments name.
Barrier-Phased Merge
A fixed worker pool runs barrier-synchronized rounds, each worker writing a deterministic value into its own slot before arriving. The completion function sums every slot with no extra lock, and the final total matches a closed-form expectation.
Atomics & Memory Ordering
A one-slot producer/consumer hand-off runs under sequential consistency, under the minimal acquire/release pairing the hand-off actually needs, and under a deliberately unsynchronized mode. The first two always complete correctly; the third reliably stalls from a compiler hoisting a stale read out of the consumer's loop.
SPSC Ring Buffer
A single-producer/single-consumer ring buffer is checked per item, not just by aggregate sum, for loss, duplication, and reordering across capacities and padding settings. A padded head/tail layout shows the throughput cost of two unrelated counters sharing one cache line.
Launch Policies & packaged_task
Explicit async and deferred launch policies are checked against the thread id each task actually ran on, not trusted on name alone. A small packaged_task worker pool proves an exception thrown by one task surfaces intact at its own future::get(), leaving every other task unaffected.
Coroutines and HALO
A co_yield-based generator and a co_await-able task type using symmetric transfer are both hand-rolled, since C++20 has no standard coroutine type. Allocation-counting probes compare a stateless coroutine against one carrying a live 4 KiB buffer across a suspension point.
Strand vs. Mutex Serialization
The identical unsynchronized counter is incremented by several threads through a shared Asio strand and directly on a multithreaded io_context. The strand always lands on the exact count with zero overlaps; posted directly, real overlaps appear.
Fibers vs. Threads
One worker loop runs unmodified over Boost.Fiber fibers and over std::thread workers, comparing peak RSS for the same work. A separate guard-page demo turns a fiber stack overflow into an immediate, contained fault instead of silent memory corruption.
seq vs par vs par_unseq
The same sort and reduction run under std::execution::seq, par, and par_unseq against one fixed dataset. The sort hash and reduction sum must match exactly across all three policies; a CPU-usage probe reports, without asserting, whether par actually spread across cores.
Shared Queue vs. Work-Stealing
A single-queue thread pool and a work-stealing pool run the identical CPU-bound task mix. A companion probe reads the real cgroup CPU quota from cpu.max and compares it against the raw host core count hardware_concurrency() reports.
NUMA Placement & Locality
A disposable two-node KVM guest, not a container, gives this demo a real NUMA topology to be remote across. numa_alloc_onnode placement, first-touch binding, and a cpuset.mems fallback are all checked directly; local-vs-remote latency is reported for context.
AoS vs. SoA & SIMD
The identical particle-update arithmetic runs scalar over an array-of-structs layout, scalar over a struct-of-arrays layout, and vectorized over struct-of-arrays with std::experimental::simd. All three must hash to bit-identical final positions.
A Harness Checked Against Itself
A trivial atomic fetch_add workload is timed with warmup, per-iteration sampling, and percentile and coordinated-omission reporting in one mode, and with a single naive wall-clock measurement in another. The missing percentile fields in naive mode are the methodology gap made visible.
False Sharing & Padding
Two pinned threads each increment their own atomic counter, with and without cache-line padding between the two counters. Correctness holds either way, but the unpadded layout runs measurably slower from coherence traffic on a line neither thread actually shares.
Disruptor-Style Sequence Barrier
One producer feeds a journal consumer and a dependent business-logic consumer over a fixed-capacity ring. Every event is checked for in-order single-consumption, the dependent stage never reads ahead of the journal, and back-pressure engages deterministically.
Back-Pressure & Load Shedding
A Boost.Beast async HTTP server enforces an in-flight-request cap with one atomic counter, answering HTTP 503 before a handler ever runs. A two-phase load test proves zero rejections below the cap and clean shedding with no dropped connections above it.
Bounded gRPC Admission
A raw CompletionQueue server implements the CallData state-machine pattern with an explicit admission cap, rejecting overflow calls with RESOURCE_EXHAUSTED instead of streaming anything. Concurrent streaming clients prove the cap holds exactly and the server drains cleanly on SIGTERM.
Real Races, Caught Live
A racy, unsynchronized counter is proven broken by a ThreadSanitizer build, independent of what any single plain run happens to print. A latch-forced AB/BA deadlock is attached to live with gdb to read the lock cycle directly off both threads' backtraces.
Two Detectors, One Bug
The same racy counter is checked under ThreadSanitizer's compile-time instrumentation and Valgrind Helgrind's lockset/happens-before hybrid, two independent algorithms agreeing on one source line. A detached thread reading through a freed buffer is caught by AddressSanitizer, naming both the allocation and the free.
Tracing Across a Thread Pool
A thread pool captures the submitting request's OpenTelemetry context and hands it to worker threads so pool.task spans nest correctly under their request.handle root. A docker compose stack with Tempo and Mimir backs every assertion with a real trace and metric query.
cgroup Quota vs. hardware_concurrency()
A probe reads cpu.max directly, derives a pool size from the tighter of the real quota and the affinity-visible core count, and runs a small CPU-bound pool-bench sized to that result instead of the host's raw core count.
Ingest / Match / Publish Pipeline
Multiple ingest producers feed a bounded MPMC ring into a single pinned matching thread running a real price-time-priority order book, which feeds a bounded multi-consumer ring to a publish pool. Sustained and overload load shapes prove conservation, single-writer discipline, and deterministic back-pressure.
Build Harness Reference Slice
A tiny shared-counter program is built with gcc (always) and clang plus ThreadSanitizer (best-effort) to check gcc-vs-clang output parity and confirm a deliberately injected race is flagged only under the TSan build. conan.lock pins the exact declared dependency end to end.
Running every demo
Clone the repo and invoke each demo.sh from its
directory. The scripts assume Docker and a
handful of host tools (hey, jq,
curl).
git clone https://github.com/patterncatalyst/cpp-concurrency-and-parallelism.git
cd cpp-concurrency-and-parallelism/examples/<chapter-slug>
./demo.sh