Boost::Asio : io_service.run() vs poll() 或者我如何在主循环中集成 boost::asio
Posted
技术标签:
【中文标题】Boost::Asio : io_service.run() vs poll() 或者我如何在主循环中集成 boost::asio【英文标题】:Boost::Asio : io_service.run() vs poll() or how do I integrate boost::asio in mainloop 【发布时间】:2011-06-09 23:26:44 【问题描述】:我目前第一次尝试将 boost::asio 用于一些简单的 tcp 网络,我已经遇到了一些我不确定如何处理的东西。据我了解 io_service.run() 方法基本上是一个循环,它一直运行到没有更多事情要做为止,这意味着它会一直运行到我释放我的小服务器对象为止。由于我已经设置了某种主循环,为了简单起见,我宁愿从那里手动更新网络循环,我认为 io_service.poll() 会做我想做的事,有点像这样:
void myApplication::update()
myioservice.poll();
//do other stuff
这似乎可行,但我仍然想知道这种方法是否存在缺点,因为这似乎不是处理 boost::asios io 服务的常用方法。这是一种有效的方法还是我应该在非阻塞额外线程中使用 io_service.run() ?
【问题讨论】:
【参考方案1】:使用io_service::poll
代替io_service::run
是完全可以接受的。区别在documentation
也可以使用 poll() 函数 调度准备好的处理程序,但是 没有阻塞。
请注意,如果队列中还有 work
,io_service::run
将阻塞
工作类用于通知 io_service 工作开始时和 完成。这确保了 io_service 对象的 run() 函数 工作正在进行时不会退出, 并且它确实在没有时退出 剩下未完成的工作。
而io_service::poll
没有表现出这种行为,它只是调用就绪的处理程序。另请注意,您需要在对io_service:run
或io_service::poll
的任何后续调用中调用io_service::reset。
【讨论】:
io_service
不一定在io_service::poll
返回后停止。为什么在后续的io_service::run
或io_service:poll
之前需要io_service::reset
?
1+ 用于 io_service::reset。如果run
没有找到任何工作,_stopped
将设置为true
,这将阻止处理任何未来添加的任务。 reset
将 _stopped
设置回 false
。【参考方案2】:
一个缺点是你会做一个繁忙的循环。
while(true)
myIoService.poll()
将使用 100% 的 CPU。 myIoService.run()
将使用 0% cpu。
myIoService.run_one()
可能会做你想做的事,但如果它无事可做,它会阻止。
【讨论】:
您确实更喜欢在这种简单的情况下运行,但是在已经存在事件循环的情况下(比如它正在做后台渲染或空闲周期中的其他事情),那么 poll 将是首选,因为您不希望游戏在每次 run() 阻塞时停止。【参考方案3】:这样的循环可以让您轮询、不忙于等待,并根据需要重置。 (我正在使用更新的 io_context
替换 io_service
。)
while (!exitCondition)
if (ioContext.stopped())
ioContext.restart();
if (!ioContext.poll())
if (stuffToDo)
doYourStuff();
else
std::this_thread::sleep_for(std::chrono::milliseconds(3));
【讨论】:
以上是关于Boost::Asio : io_service.run() vs poll() 或者我如何在主循环中集成 boost::asio的主要内容,如果未能解决你的问题,请参考以下文章
boost::asio::io_service 运行方法阻塞/解除阻塞时感到困惑
C++ boost::asio::io_service创建线程池thread_group简单实例