1

我已经使用 boost::asio 库实现了客户端服务器程序。在我的实现中,有时 io_service.run() 会无限期地阻塞。如果我将另一个请求传递给 io_service,则被阻止的调用开始正常执行。

有什么方法可以查看 io_service 队列中的待处理请求是什么?

我没有使用工作对象来阻止运行调用!

4

2 回答 2

0

没有官方方法可以查询io_service以查找所有待处理的请求。但是,有一些技术可以调试问题:

  • Boost 1.47 引入了处理程序跟踪。只需简单定义BOOST_ASIO_ENABLE_HANDLER_TRACKING,Boost.Asio 就会将调试输出(包括时间戳、标识符和操作类型)写入标准错误流。
  • 附加调试器挖掘层以查找和检查操作队列。此答案涵盖理解处理程序跟踪和使用调试器检查epoll_reactor.

最后,如果您认为这是一个错误,那么可能值得更新到最新版本或检查修订历史以了解相关更改。无论如何,更详细地描述问题可以让其他人帮助确定问题的根源和潜在的解决方案。

于 2013-11-12T13:05:13.297 回答
0

现在我花了几个小时阅读和试验(我也需要更多的 boost::asio 功能来工作),结果证明:有点。但它并不像人们希望的那样简单易读。

在引擎盖下(好吧,在最外面的引擎盖下)io_service 注册了一堆其他服务,它们完成async_各自领域所需的工作操作。这些是参考中描述的“服务”。现在可悲的是,无论是否有工作要做,服务都保持注册状态。例如,如果您的 io_service 有一个 udp 套接字,它仍然会拥有所有相应的服务,即使套接字本身处于非活动状态。

但是你可以询问你的 io_service 它有哪些服务。假设您想知道您调用的 io_service 是否m_io_service有 udp datagram_socket_service。然后你可以调用类似的东西:

if (boost::asio::has_service<boost::asio::datagram_socket_service<boost::asio::ip::udp> >(m_io_service))
{
    //Whatever
}

这没有多大帮助,因为无论套接字是否处于活动状态,它都是正确的。但是在你知道你有那个服务之后,你可以使用同样优雅的 <> 来获得它的use_service引用has_service。现在您可以检查该服务以了解它在做什么。可悲的是,它不会告诉您出色的处理程序名称是什么(可能部分是因为它不知道它们),但如果它是一个套接字,您可以获取它implemention_type并检查它是否当前is_openlocal_endpoint找到remote_endpoint.

如果是,deadline_timer_service您可以在其他情况下找出它的时间expires_at

有关服务是什么以及不愿意告诉您的更多信息,请参阅参考资料。 http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html

然后,这些信息应该可以让您确定哪个async_操作没有返回。如果没有,至少您可以cancel提供任何意外的活动服务。

于 2013-11-12T11:54:54.333 回答