What’s the proper usage of settings up a thread pool for io_service? These 2 statements from the documentation are throwing me off:
io_service::run
A normal exit from the run() function implies that the io_service object is stopped (the stopped() function returns true). Subsequent calls to run(), run_one(), poll() or poll_one() will return immediately unless there is a prior call to reset().
io_service::reset
This function must be called prior to any second or later set of invocations of the run(), run_one(), poll() or poll_one() functions when a previous invocation of these functions returned due to the io_service being stopped or running out of work.
Here’s what I’m currently doing:
boost::thread_group m_Threads;
boost::asio::io_service m_IoService;
boost::barrier m_Barrier(numThreads);
for( unsigned int i = 0; i < numThreads; ++i )
{
m_Threads.create_thread(
[&]()
{
for(;;)
{
m_IoService.run();
if( m_Barrier.wait() ) // will only return true for 1 thread
{
m_IoService.reset();
}
m_Barrier.wait();
}
});
}
m_IoService.stop();
m_Threads.interrupt_all();
m_Threads.join_all();
Everything seems to work fine if I just put m_IoService.run() in an infinite loop (which the documentation seems to indicate should not be the case). What’s the correct way?
run()is a blocking call, and will execute all events that it can before returning. It will only return if there are no more events to handle. Once it returns, you must callreset()on the io_service before callingrun()again.You can have multiple threads calling
run()– this is not a problem, and you don’t need the infinite loop as long as the io_service has some work to do. The normal pattern for this is to create aworkobject on the io_service which will forcerun()to never return. This does mean that you explicitly have to callstop()on the io_service when you are done as it will never naturally exit.If you setup a
workon the io_service, it will never naturally exit and therefore you will never need to callreset().Now all threads are dispatching events on the io_service