7

Whats the difference between an asio::thread_pool and an asio::io_context whose run() function is called from multiple threads? Can I replace my boost::thread_group of threads that call io_context::run() with an asio::thread_pool? Or do I need somewhere an io_context?

Update

When I use asio::thread_pool, do I still need an io_context to use sockets, timers, etc? Both thread_pool and io_context are an asio::execution_context. However, the docs say on io_context that it "Provides core I/O functionality". Do I lose these if I only use an asio::thread_pool without an io_context?

Waqar
  • 8,558
  • 4
  • 35
  • 43

1 Answers1

7

A threadpool implicit runs all the tasks posted on it (until it's stopped).

An io_service doesn't assume anything about the threads that will run it: you need to make sure you do that, and you're free to decide whether you run it on multiple threads, one thread, or even a mix (like one thread at at time, but from multiple threads?).

Further notes:

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Excellent points and links, thanks! I'll consider these. One thing is still unclear to me (I've updated the question): Do I need an io_service to use sockets and timers? Or does the thread_pool provide the same functionalities? – Valar Morghulis May 19 '20 at 06:17
  • @ValarMorghulis Both `io_context` and `thread_pool` are perfectly capable [`execution_context`](https://www.boost.org/doc/libs/1_73_0/doc/html/boost_asio/reference/execution_context.html) instances. In fact, for specific services using only one execution context could be more efficient than multiple. See https://stackoverflow.com/a/33529876/85371 or https://stackoverflow.com/questions/6055496/are-multiple-asio-io-services-a-good-thing – sehe May 19 '20 at 14:03
  • You can control how threads are created and then attached to a thread_pool. Initialize an empty pool by calling the thread_pool constructor with integer argument and passing 0. Then create your threads and call the thread_pool.attach() method. Simplest example: auto* t = new std::thread([](){pool.attach()}); – muusbolla Mar 28 '22 at 03:07
  • @muusbolla Do not use `new` there (consider maybe `detach()` instead). Also, that's not full control: It's merely the option to _grow_, never shrink. That could be very important if your threads need thread-local initializations (like `mysql_thread_init`, or your own singleton instances) – sehe Mar 28 '22 at 20:57