【问题标题】:boost::asio io_service thread pool with io_service::workboost::asio io_service 线程池和 io_service::work
【发布时间】:2017-09-17 17:01:28
【问题描述】:

我有一个 boost::asio 线程池,它有一个 asio::io_serviceasio::work:
boost::asio::io_service m_service;
boost::asio::io_service::work m_work;
在线程池析构函数中,我调用m_service.stop(),然后加入所有线程。但是在进程关闭期间(在线程池析构函数中)间歇性地遇到此崩溃:

#0 0x0000000000000000 in ?? () #1 0x00007f4c8e59d160 in boost::asio::detail::task_io_service_operation::destroy ( this=0x6d579f8) at /home/depot/Boost_1_61_0/boost/asio/detail/task_io_service_operation.hpp:43 #2 0x00007f4c8e59d115 in boost::asio::detail::op_queue_access::destroy (o=0x6d579f8) at /home/depot/Boost_1_61_0/boost/asio/detail/op_queue.hpp:47 #3 0x00007f4c8e59d044 in boost::asio::detail::op_queue::~op_queue (this=0x6d57a20) at /home/depot/Boost_1_61_0/boost/asio/detail/op_queue.hpp:81 #4 0x00007f4c8e685d65 in boost::asio::detail::task_io_service::~task_io_service ( this=0x6d57960) at /home/depot/Boost_1_61_0/boost/asio/detail/task_io_service.hpp:40 #5 0x00007f4c8e685dc9 in boost::asio::detail::task_io_service::~task_io_service ( this=0x6d57960) at /home/depot/Boost_1_61_0/boost/asio/detail/task_io_service.hpp:40 #6 0x00007f4c8e5aa1ce in boost::asio::detail::service_registry::destroy ( service=0x6d57960) at /home/depot/Boost_1_61_0/boost/asio/detail/impl/service_registry.ipp:101 #7 0x00007f4c8e68537c in boost::asio::detail::service_registry::~service_registry ( this=0x6d55020) at /home/depot/Boost_1_61_0/boost/asio/detail/impl/service_registry.ipp:45 #8 0x00007f4c8e6852b0 in boost::asio::io_service::~io_service ( this=0x7f4c8eb169c8 ) at /home/depot/Boost_1_61_0/boost/asio/impl/io_service.ipp:53 #9 0x00007f4c8e71d295 in crossplat::threadpool::~threadpool ( this=0x7f4c8eb169b0 ) at /home/depot/include/threadpool.h:87 #10 0x00007f4c8aed6fe8 in __run_exit_handlers (status=0, ---Type to continue, or q to quit--- listp=0x7f4c8b2605f8 , run_list_atexit=run_list_atexit@entry=true) at exit.c:82 #11 0x00007f4c8aed7035 in __GI_exit (status=) at exit.c:104 #12 0x00007f4c8aebd837 in __libc_start_main (main=0x1ce0980 , argc=3, argv=0x7fffee2eda98, init=, fini=, rtld_fini=, stack_end=0x7fffee2eda88) at ../csu/libc-start.c:325 #13 0x0000000001cdf159 in _start () at /usr/include/c++/v1/string:2027

asio 文档建议显式销毁 asio::work 对象,以便所有处理程序正常完成。问题:

  1. 显式销毁 asio::work 对象后是否需要调用io_service::stop()
  2. io_service::stop()和销毁io_service::work有什么区别
  3. 这个线程池析构函数看起来是否正确,它可以帮助修复上述崩溃。我已将 m_work 更改为指针 std::unique_ptr<boost::asio::io_service::work> m_work;:
    ~threadpool()
    {
    m_work.reset(); // Allow io_service::run to exit
    // join all threads
    }

【问题讨论】:

  • 我相当肯定,如果没有发布的工作,您不会调用 io_service.stop。您可以通过查看 io_service::run 在工作被破坏后是否返回来测试这一点。确保您实际上等待线程退出并调用加入。我从来没有使用过线程池,所以我没有资格给出完整的答案。
  • @ChristopherPisz 线程池必须是他自己的代码

标签: c++ boost threadpool asio


【解决方案1】:

显式销毁asio::work对象后是否需要调用io_service::stop()?

没有。如果没有更多工作,服务将完成(poll/run 将返回)。

io_service::stop()和销毁io_service::work有什么区别

工作只是释放锁,允许服务完成。

io_service::stop() 强制停止事件循环,即使还有待处理的工作。

这个线程池析构函数看起来是否正确,它可以帮助修复上述崩溃。

是的,析构函数应该加入所有线程。你的代码没有显示它,所以我建议你验证一下。

想法

我注意到 threadpool 正在从退出处理程序中销毁。这 - 对我来说 - 意味着线程池可能具有静态存储持续时间。如果它还依赖于其他任何东西(例如,可能是静态 io_service 实例?),您可能会遇到 SIOF:静态初始化订单惨败。

【讨论】:

    猜你喜欢
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 2011-06-16
    相关资源
    最近更新 更多