【发布时间】:2011-12-18 21:56:49
【问题描述】:
为 io_service 设置线程池的正确用法是什么?来自documentation 的这两条语句让我大吃一惊:
io_service::run
run() 函数的正常退出意味着 io_service 对象已停止(stopped() 函数返回 true)。除非之前调用了 reset(),否则对 run()、run_one()、poll() 或 poll_one() 的后续调用将立即返回。
io_service::reset
当由于 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() 放入无限循环中,一切似乎都可以正常工作(文档似乎表明不是应该是这种情况)。 正确的方法是什么?
【问题讨论】:
-
据我了解,您只调用了一次 run,它仅在没有更多工作排队时才返回。我从来没有循环调用它。不过我可能误解了一些东西
-
@JohnB 好吧,我已经得到了所有这些对象,这些对象在整个地方都使用 io_service 读写等等。完全有可能 io_service 会暂时停止工作,然后再次排队等待更多工作,不是吗?我正在尝试处理这种情况,并且还分布在多个线程上。
-
这个想法是,在完成处理您正在处理的请求之前,您总是将下一个读取或写入请求排队。如果你不能这样做,你可以使用这里描述的工作对象boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/…
-
@JohnB 解决你的第一句话:在我的代码中,许多系统/线程在他们认为合适的时候执行读/写。他们彼此不了解,并且可能有也可能没有足够的work 来保持 io_service 的队列在应用程序的整个生命周期内不为空。我无法想象 asio 的重要用途可以保证 io_service 的不间断工作流。
标签: c++ networking boost boost-asio c++11