thread_pool.ipp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //
  2. // impl/thread_pool.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_IMPL_THREAD_POOL_IPP
  11. #define BOOST_ASIO_IMPL_THREAD_POOL_IPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <stdexcept>
  17. #include <boost/asio/thread_pool.hpp>
  18. #include <boost/asio/detail/throw_exception.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. struct thread_pool::thread_function
  23. {
  24. detail::scheduler* scheduler_;
  25. void operator()()
  26. {
  27. #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
  28. try
  29. {
  30. #endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
  31. boost::system::error_code ec;
  32. scheduler_->run(ec);
  33. #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
  34. }
  35. catch (...)
  36. {
  37. std::terminate();
  38. }
  39. #endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
  40. }
  41. };
  42. #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  43. long thread_pool::default_thread_pool_size()
  44. {
  45. std::size_t num_threads = detail::thread::hardware_concurrency() * 2;
  46. num_threads = num_threads == 0 ? 2 : num_threads;
  47. return static_cast<long>(num_threads);
  48. }
  49. thread_pool::thread_pool()
  50. : scheduler_(boost::asio::make_service<detail::scheduler>(*this, false)),
  51. threads_(allocator<void>(*this)),
  52. num_threads_(default_thread_pool_size()),
  53. joinable_(true)
  54. {
  55. start();
  56. }
  57. #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  58. long thread_pool::clamp_thread_pool_size(std::size_t n)
  59. {
  60. if (n > 0x7FFFFFFF)
  61. {
  62. std::out_of_range ex("thread pool size");
  63. boost::asio::detail::throw_exception(ex);
  64. }
  65. return static_cast<long>(n & 0x7FFFFFFF);
  66. }
  67. thread_pool::thread_pool(std::size_t num_threads)
  68. : execution_context(config_from_concurrency_hint(num_threads == 1 ? 1 : 0)),
  69. scheduler_(boost::asio::make_service<detail::scheduler>(*this, false)),
  70. threads_(allocator<void>(*this)),
  71. num_threads_(clamp_thread_pool_size(num_threads)),
  72. joinable_(true)
  73. {
  74. start();
  75. }
  76. thread_pool::thread_pool(std::size_t num_threads,
  77. const execution_context::service_maker& initial_services)
  78. : execution_context(initial_services),
  79. scheduler_(boost::asio::make_service<detail::scheduler>(*this, false)),
  80. threads_(allocator<void>(*this)),
  81. num_threads_(clamp_thread_pool_size(num_threads)),
  82. joinable_(true)
  83. {
  84. start();
  85. }
  86. thread_pool::~thread_pool()
  87. {
  88. stop();
  89. join();
  90. shutdown();
  91. }
  92. void thread_pool::start()
  93. {
  94. scheduler_.work_started();
  95. thread_function f = { &scheduler_ };
  96. threads_.create_threads(f, static_cast<std::size_t>(num_threads_));
  97. }
  98. void thread_pool::stop()
  99. {
  100. scheduler_.stop();
  101. }
  102. void thread_pool::attach()
  103. {
  104. ++num_threads_;
  105. thread_function f = { &scheduler_ };
  106. f();
  107. }
  108. void thread_pool::join()
  109. {
  110. if (joinable_)
  111. {
  112. joinable_ = false;
  113. scheduler_.work_finished();
  114. threads_.join();
  115. }
  116. }
  117. void thread_pool::wait()
  118. {
  119. join();
  120. }
  121. } // namespace asio
  122. } // namespace boost
  123. #include <boost/asio/detail/pop_options.hpp>
  124. #endif // BOOST_ASIO_IMPL_THREAD_POOL_IPP