【问题标题】:boost::asio hangs in resolver service destructor after throwing out of io_service::run()boost::asio 在抛出 io_service::run() 后挂在解析器服务析构函数中
【发布时间】:2011-03-20 10:51:42
【问题描述】:

我正在使用一个相当简单的 boost::asio 设置,我从主线程调用 io_service.run()。 我有一个 tcp 解析器,并使用 async resolve 来查找地址。 当查找失败时,我会在异步回调中抛出异常。 我在主函数内部的 run() 调用之外捕获了这个异常。然后我在我的 io_service 实例(它是一个全局的)上调用 stop() 。 但是,当 main() 返回时,程序会挂起。事实证明,它正在等待一个永远不会来自解析器服务的 exit_event_。

我不想在退出时挂起。有什么我做错了吗?如果是这样,是什么?我在网上没有找到很多关于这些事情的讨论。 我在 Windows 7/64bit 上使用 boost 1.41.0。

【问题讨论】:

  • 只是为了澄清:io_service.run 返回 - 你在调用 io_service.run 的 try-catch 中捕获异常?请提供代码 sn-p 演示问题。
  • 如果没有重现问题的代码,几乎无法提供帮助。
  • 我有完全相同的问题,抛出异常不是线程也不是回调,而是在对象方法中,当其他对象(服务器和客户端,发布异步监听作业)我在 try 中捕获异常捕获包装 io_service.run() et 调用 return 1;但程序永远不会退出......并停留在 io_service 析构函数中......你解决了这个问题吗?我们的项目是基于 asio 和 im effraid 使用一个有缺陷的库...
  • 好吧,我明白为什么了,我已经解决了;)

标签: c++ boost boost-asio resolver


【解决方案1】:

stop() 只是通知 io_service 停止。如果您在 stop() 调用之后使用另一个 run() 调用,它应该会返回并正确清理。

documentation 中有一些关于从处理程序中抛出异常的讨论。

我也猜测这个问题可能与某些对象生命周期问题有关,例如io 服务被破坏,而其他东西仍在引用它。仔细查看示例以及如何使用共享指针来确保对象仍然存在。

【讨论】:

    【解决方案2】:

    然后我在我的 io_service 上调用 stop()

    当你需要停止io_service时尝试使用这个技巧(复制自io_service documentation):

    boost::asio::io_service io_service;
    auto_ptr<boost::asio::io_service::work> work(
        new boost::asio::io_service::work(io_service));
    ...
    work.reset(); // Allow run() to exit. 
    

    原因很简单(也来自文档):调用io_service::stop() 将导致 io_service run() 调用尽快返回,放弃未完成的操作并且不允许调度准备好的处理程序。

    因此,如果您需要调度所有处理程序,调用 io_service::stop() 是不够的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-14
      相关资源
      最近更新 更多