asio::thread_pool 在调用构造函数之前就失败了

asio::thread_pool fails before constructor is even called

我正在尝试实现线程池并发现了 asio::thread_pool。我创建了一个简单的 class 来使用线程池,但它甚至在到达我的 class 的构造函数之前就失败了:

.hpp

namespace asio {
  namespace detail {

    template <typename Exception>
    void throw_exception(const asio::invalid_service_owner &service_owner) {
      std::cerr << "Something just happened: " << service_owner.what() << std::endl;
      std::terminate();
    }

    template <typename Exception>
    void throw_exception(const Exception &e) {
      std::cerr << "Something just happened: " << e.what() << std::endl;
      std::terminate();
    }
  }  // namespace detail
}  // namespace asio

namespace dbc {

  namespace detail {

    /// \brief Connection pool.
    struct pool : public std::enable_shared_from_this<pool> {
      // Make object non-copyable.
      pool(const pool &) = delete;
      auto operator=(const pool &) -> pool & = delete;

      /// \brief Constructor
      /// \param[in] config Configuration data supplied by the end user.
      explicit pool(const pool_parameters &config) noexcept;

      pool_parameters m_config;
      /// \brief Thread pool where tasks are asynchrinously executed.
      asio::thread_pool m_t_pool;
    };
  }  // namespace detail
}  // namespace dbc

.cpp

pool::pool(const pool_parameters& config) noexcept : m_config{config} {}

我还有一个测试只创建了一个 std::shared_ptr 池:

auto p = std::make_shared<pool>(conf);

并且崩溃并出现以下错误:

线程:套接字不支持操作

和以下堆栈跟踪:

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x00007fff6418d23e libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff64243c1c libsystem_pthread.dylib`pthread_kill + 285
    frame #2: 0x00007fff640f61c9 libsystem_c.dylib`abort + 127
    frame #3: 0x00007fff61776231 libc++abi.dylib`abort_message + 231
    frame #4: 0x00007fff617762f4 libc++abi.dylib`default_terminate_handler() + 48
    frame #5: 0x00007fff61781dfe libc++abi.dylib`std::__terminate(void (*)()) + 8
    frame #6: 0x00007fff61781e85 libc++abi.dylib`std::terminate() + 69
    frame #7: 0x0000000100005409 integration`void asio::detail::throw_exception<std::__1::system_error>(e=0x00007ffeefbfd5c0) at pool.hpp:23
    frame #8: 0x0000000100005364 integration`asio::detail::do_throw_error(err=0x00007ffeefbfd668, location="thread") at throw_error.ipp:49
    frame #9: 0x0000000100005312 integration`asio::detail::throw_error(err=0x00007ffeefbfd668, location="thread") at throw_error.hpp:41
    frame #10: 0x00000001000052b1 integration`asio::detail::null_thread::null_thread<asio::thread_pool::thread_function>(this=0x0000000101002d20, (null)=thread_function @ 0x00007ffeefbfd688, (null)=0) at null_thread.hpp:39
    frame #11: 0x00000001000051e3 integration`asio::detail::null_thread::null_thread<asio::thread_pool::thread_function>(this=0x0000000101002d20, (null)=thread_function @ 0x00007ffeefbfd6f8, (null)=0) at null_thread.hpp:38
    frame #12: 0x00000001000051a4 integration`asio::detail::thread_group::item::item<asio::thread_pool::thread_function>(this=0x0000000101002d20, f=thread_function @ 0x00007ffeefbfd738, next=0x0000000000000000) at thread_group.hpp:73
    frame #13: 0x0000000100005165 integration`asio::detail::thread_group::item::item<asio::thread_pool::thread_function>(this=0x0000000101002d20, f=thread_function @ 0x00007ffeefbfd768, next=0x0000000000000000) at thread_group.hpp:75
    frame #14: 0x0000000100005100 integration`void asio::detail::thread_group::create_thread<asio::thread_pool::thread_function>(this=0x0000000101002f98, f=thread_function @ 0x00007ffeefbfd7b8) at thread_group.hpp:44
    frame #15: 0x0000000100003d87 integration`void asio::detail::thread_group::create_threads<asio::thread_pool::thread_function>(this=0x0000000101002f98, f=thread_function @ 0x00007ffeefbfd7f8, num_threads=2) at thread_group.hpp:52
    frame #16: 0x0000000100003c06 integration`asio::thread_pool::thread_pool(this=0x0000000101002f88) at thread_pool.ipp:43
    frame #17: 0x0000000100002a35 integration`asio::thread_pool::thread_pool(this=0x0000000101002f88) at thread_pool.ipp:38
    frame #18: 0x00000001000029ab integration`dbc::detail::pool::pool(this=0x0000000101002f28, config=0x00007ffeefbfe2b8) at pool.cpp:9
    frame #19: 0x0000000100002a8d integration`dbc::detail::pool::pool(this=0x0000000101002f28, config=0x00007ffeefbfe2b8) at pool.cpp:9
    frame #20: 0x0000000100159523 integration`std::__1::shared_ptr<dbc::detail::pool> std::__1::shared_ptr<dbc::detail::pool>::make_shared<dbc::pool_parameters&>(dbc::pool_parameters&&&) [inlined] std::__1::__compressed_pair_elem<dbc::detail::pool, 1, false>::__compressed_pair_elem<dbc::pool_parameters&, 0ul>(this=0x0000000101002f28, __args=size=1) at memory:2103
    frame #21: 0x00000001001594f5 integration`std::__1::shared_ptr<dbc::detail::pool> std::__1::shared_ptr<dbc::detail::pool>::make_shared<dbc::pool_parameters&>(dbc::pool_parameters&&&) [inlined] std::__1::__compressed_pair<std::__1::allocator<dbc::detail::pool>, dbc::detail::pool>::__compressed_pair<std::__1::allocator<dbc::detail::pool>&, dbc::pool_parameters&>(this=0x0000000101002f28, __first_args=size=1, __second_args=size=1) at memory:2205
    frame #22: 0x000000010015945d integration`std::__1::shared_ptr<dbc::detail::pool> std::__1::shared_ptr<dbc::detail::pool>::make_shared<dbc::pool_parameters&>(dbc::pool_parameters&&&) [inlined] std::__1::__compressed_pair<std::__1::allocator<dbc::detail::pool>, dbc::detail::pool>::__compressed_pair<std::__1::allocator<dbc::detail::pool>&, dbc::pool_parameters&>(this=0x0000000101002f28, __pc=piecewise_construct_t @ 0x00007ffeefbfdd10, __first_args=size=1, __second_args=size=1) at memory:2206
    frame #23: 0x0000000100159433 integration`std::__1::shared_ptr<dbc::detail::pool> std::__1::shared_ptr<dbc::detail::pool>::make_shared<dbc::pool_parameters&>(dbc::pool_parameters&&&) [inlined] std::__1::__shared_ptr_emplace<dbc::detail::pool, std::__1::allocator<dbc::detail::pool> >::__shared_ptr_emplace<dbc::pool_parameters&>(this=0x0000000101002f10, __a=allocator<dbc::detail::pool> @ 0x00007ffeefbfdcd0, __args=0x00007ffeefbfe2b8) at memory:3618
    frame #24: 0x00000001001591ea integration`std::__1::shared_ptr<dbc::detail::pool> std::__1::shared_ptr<dbc::detail::pool>::make_shared<dbc::pool_parameters&>(dbc::pool_parameters&&&) [inlined] std::__1::__shared_ptr_emplace<dbc::detail::pool, std::__1::allocator<dbc::detail::pool> >::__shared_ptr_emplace<dbc::pool_parameters&>(this=0x0000000101002f10, __a=allocator<dbc::detail::pool> @ 0x00007ffeefbfdca0, __args=0x00007ffeefbfe2b8) at memory:3619
    frame #25: 0x00000001001591ce integration`std::__1::shared_ptr<dbc::detail::pool> std::__1::shared_ptr<dbc::detail::pool>::make_shared<dbc::pool_parameters&>(__args=0x00007ffeefbfe2b8) at memory:4277
    frame #26: 0x000000010015890e integration`____C_A_T_C_H____T_E_S_T____0() [inlined] std::__1::enable_if<!(is_array<dbc::detail::pool>::value), std::__1::shared_ptr<dbc::detail::pool> >::type std::__1::make_shared<dbc::detail::pool, dbc::pool_parameters&>(__args=0x00007ffeefbfe2b8) at memory:4656
    frame #27: 0x00000001001588f6 integration`____C_A_T_C_H____T_E_S_T____0() at pool.cpp:16
    frame #28: 0x0000000100044da3 integration`Catch::TestInvokerAsFunction::invoke(this=0x0000000101002ac0) const at catch.hpp:11605
    frame #29: 0x0000000100031937 integration`Catch::TestCase::invoke(this=0x0000000101005f20) const at catch.hpp:11506
    frame #30: 0x000000010003182d integration`Catch::RunContext::invokeActiveTestCase(this=0x00007ffeefbff308) at catch.hpp:10365
    frame #31: 0x000000010002d17b integration`Catch::RunContext::runCurrentTest(this=0x00007ffeefbff308, redirectedCout="", redirectedCerr="") at catch.hpp:10339
    frame #32: 0x000000010002aa47 integration`Catch::RunContext::runTest(this=0x00007ffeefbff308, testCase=0x0000000101005f20) at catch.hpp:10115
    frame #33: 0x00000001000362f9 integration`Catch::(anonymous namespace)::runTests(config=std::__1::shared_ptr<Catch::Config>::element_type @ 0x0000000101003188 strong=4 weak=1) at catch.hpp:10667
    frame #34: 0x0000000100034ea6 integration`Catch::Session::runInternal(this=0x00007ffeefbff780) at catch.hpp:10862
    frame #35: 0x0000000100034b85 integration`Catch::Session::run(this=0x00007ffeefbff780) at catch.hpp:10819
    frame #36: 0x000000010007264a integration`int Catch::Session::run<char>(this=0x00007ffeefbff780, argc=2, argv=0x00007ffeefbff8f8) at catch.hpp:10565
    frame #37: 0x0000000100072592 integration`main(argc=2, argv=0x00007ffeefbff8f8) at catch.hpp:14318
    frame #38: 0x00007fff6404ded9 libdyld.dylib`start + 1
    frame #39: 0x00007fff6404ded9 libdyld.dylib`start + 1

我的测试名为 "integration",我正在使用 Catch 测试框架。

如果我在 pool 的析构函数上调用 m_t_pool.join() 也没有用。

这非常令人困惑,因为根据文档我应该能够自己创建 thread_pool 的实例。

这是我的 Cmake 配置:

target_compile_definitions(
  ${PROJECT_NAME}
    PRIVATE
      ASIO_STANDALONE=1
      ASIO_NO_EXCEPTIONS=1
      ASIO_NO_DEPRECATED=1
      ASIO_DISABLE_THREADS=1
)

您似乎收到了 asio::nul_thread 构造函数抛出的异常:https://github.com/chriskohlhoff/asio/blob/22afb86087a77037cd296d27134756c9b0d2cb75/asio/include/asio/detail/null_thread.hpp#L39

这只会在 ASIO_HAS_THREADS 未定义时发生。

您对 ASIO_DISABLE_THREADS=1 的定义导致 ASIO_HAS_THREADS 的自动定义被禁用,您应该将其删除。