为io_service设置线程池的正确用法是什么?来自documentation的这两个陈述让我失望:
run()函数的正常退出意味着io_service对象已停止(stopped()函数返回true)。除非事先调用reset(),否则对run(),run_one(),poll()或poll_one()的后续调用将立即返回。
当由于io_service被停止或者由于io_service被停止而返回先前调用这些函数时,必须在run(),run_one(),poll()或poll_one()函数的任何第二次或更高版本的调用之前调用此函数。失业了。
以下是我目前正在做的事情:
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();
如果我只是将m_IoService.run()
放在一个无限循环中(文档似乎表明不就是这种情况),一切似乎都能正常工作。什么是正确的方式?
答案 0 :(得分:17)
run()
是一个阻塞调用,将在返回之前执行它可以执行的所有事件。只有在没有更多事件需要处理时它才会返回。返回后,您必须在io_service上调用reset()
,然后再次调用run()
。
你可以让多个线程调用run()
- 这不是问题,只要io_service有一些工作要做,你就不需要无限循环。正常模式是在io_service上创建一个work
对象,这将迫使run()
永远不会返回。这意味着你必须在完成后明确地在io_service上调用stop()
,因为它永远不会自然退出。
如果您在io_service上设置work
,它将永远不会自然退出,因此您永远不需要致电reset()
。
work some_work(m_IoService); // this will keep the io_service live.
for( unsigned int i = 0; i < numThreads; ++i )
{
m_Threads.create_thread(
[&]()
{
m_IoService.run();
});
}
现在所有线程都在io_service
上调度事件// Now post your jobs
m_IoService.post(boost::bind(...)); // this will be executed in one of the threads
m_IoService.post(boost::bind(...)); // this will be executed in one of the threads
m_IoService.post(boost::bind(...)); // this will be executed in one of the threads
m_IoService.stop(); // explicitly stop the io_service
// now join all the threads and wait for them to exit