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
的自动定义被禁用,您应该将其删除。
我正在尝试实现线程池并发现了 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
的自动定义被禁用,您应该将其删除。