Chapter 12 — Strand vs. Mutex: Serialization Without a Lock
A strand serializes handlers without a mutex — the same unsynchronized counter comes back exact through a strand and measurably wrong posted straight to a multithreaded io_context.
The full source for this example lives in
examples/concurrency/12-asio-strand/— clone the repo,cdin, and./demo.sh.
Chapter reference: Doc 12 — Async Runtimes and Event Loops
What it shows
N copies of one handler are posted either through a shared asio::strand or straight to a multithreaded io_context; the handler deliberately widens its own race window so the no-strand case’s overlap is a deterministic, CI-reliable signal rather than a coin flip on a quiet host. Through the strand, the counter always lands exactly on the expected total with zero observed overlaps — Asio’s own serialization guarantee holding regardless of how long a handler occupies its thread; posted directly, real interleaving shows up. A second pair of modes compares the same always-correct work guarded by a strand versus a std::mutex, using each thread’s own voluntary-context-switch count as a portable proxy for how often work had to cross into the kernel.
Running it
cd examples/concurrency/12-asio-strand
./demo.sh # build + run asio_strand (all four modes) + verify.lua
./demo.sh --clean # remove the image