boost · advanced

Boost.Asio: Scaling io_context Across a Thread Pool

To exploit multiple cores in Asio you have several threads call run() on the same io_context, so ready handlers are dispatched across all of them — a thread-pooled event loop that parallelizes handler execution while sharing a single queue. That concurrency, however, reintroduces races on shared and per-connection state, which is exactly what strands solve: binding each connection's handlers to its own strand serializes them while different connections run on different pool threads, making strands-plus-a-thread-pool the standard scalable Asio design. Size the pool around hardware_concurrency for CPU-bound handlers and keep every handler short and non-blocking, offloading any blocking or heavy computation to a separate pool so an I/O thread is never stalled. A popular high-performance alternative, common in HFT systems, is the thread-per-core model: give each core its own io_context in a shared-nothing arrangement, pin the thread to the core, and avoid cross-thread synchronization altogether.

🔑 Key line

Run N threads calling run() on one io_context to dispatch handlers across cores. That makes handlers concurrent, so use a per-connection strand to serialize each connection's state while connections run in parallel. Size ≈ cores, keep handlers short/non-blocking, offload blocking work. Alternative: thread-per-core, an io_context per core (shared-nothing), common in HFT.

The code

boost::asio::io_context io;
std::vector<std::thread> pool;
for (int i = 0; i < std::thread::hardware_concurrency(); ++i)
pool.emplace_back([&]{ io.run(); }); // N threads share one context
// per-connection strands keep each connection's handlers serialized
for (auto& t : pool) t.join();

What this lesson walks through

  1. 01One context, N threads on run()
  2. 02Now you need strands
  3. 03Sizing & the thread-per-core alternative

To use all your cores, have several threads call run() on the SAME io_context. Ready handlers are then dispatched across those threads — a thread-pooled event loop that parallelizes handler work while still sharing one queue.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of Boost.Asio: Scaling io_context Across a Thread Pool and 100+ animated C++ interview lessons.

← Previous
Boost.Asio: An Async TCP Echo Server
Next →
Track a Running Process — What Is PID 1234 Doing?