Chapter 10 — Launch Policies and a packaged_task Worker Pool
std::async's default launch policy is a silent correctness gap, not a guarantee of concurrency — the only way to know whether a task actually ran concurrently is to ask it which thread it ran on.
The full source for this example lives in
examples/concurrency/10-futures-promises-packaged-tasks/— clone the repo,cdin, and./demo.sh.
Chapter reference: Doc 10 — Futures, Promises, and Packaged Tasks
What it shows
One binary submits identical callables under std::launch::async, std::launch::deferred, and the default policy, with every callable reporting the thread id it actually executed on — async must always land on a thread distinct from the submitter, deferred must always run on the submitter’s own thread inside future::get(), and the default is reported without asserting a direction either way. A second binary is a small fixed-size thread pool built on std::packaged_task, where one task throws; that exception is rethrown intact at exactly that task’s own future::get(), and every other task’s result is unaffected. Both halves are checked as hard assertions, since they’re standard-mandated guarantees rather than performance claims a busy host could mute.
Running it
cd examples/concurrency/10-futures-promises-packaged-tasks
./demo.sh # build + run launch_policy/worker_pool + verify.lua
./demo.sh --clean # remove the image