thread_group.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //
  2. // detail/thread_group.hpp
  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_DETAIL_THREAD_GROUP_HPP
  11. #define BOOST_ASIO_DETAIL_THREAD_GROUP_HPP
  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 <boost/asio/detail/memory.hpp>
  17. #include <boost/asio/detail/thread.hpp>
  18. #include <boost/asio/detail/push_options.hpp>
  19. namespace boost {
  20. namespace asio {
  21. namespace detail {
  22. template <typename Allocator>
  23. class thread_group
  24. {
  25. public:
  26. // Constructor initialises an empty thread group.
  27. explicit thread_group(const Allocator& a)
  28. : allocator_(a),
  29. first_(0)
  30. {
  31. }
  32. // Destructor joins any remaining threads in the group.
  33. ~thread_group()
  34. {
  35. join();
  36. }
  37. // Create a new thread in the group.
  38. template <typename Function>
  39. void create_thread(Function f)
  40. {
  41. first_ = allocate_object<item>(allocator_, allocator_, f, first_);
  42. }
  43. // Create new threads in the group.
  44. template <typename Function>
  45. void create_threads(Function f, std::size_t num_threads)
  46. {
  47. for (std::size_t i = 0; i < num_threads; ++i)
  48. create_thread(f);
  49. }
  50. // Wait for all threads in the group to exit.
  51. void join()
  52. {
  53. while (first_)
  54. {
  55. first_->thread_.join();
  56. item* tmp = first_;
  57. first_ = first_->next_;
  58. deallocate_object(allocator_, tmp);
  59. }
  60. }
  61. // Test whether the group is empty.
  62. bool empty() const
  63. {
  64. return first_ == 0;
  65. }
  66. private:
  67. // Structure used to track a single thread in the group.
  68. struct item
  69. {
  70. template <typename Function>
  71. explicit item(const Allocator& a, Function f, item* next)
  72. : thread_(std::allocator_arg, a, f),
  73. next_(next)
  74. {
  75. }
  76. boost::asio::detail::thread thread_;
  77. item* next_;
  78. };
  79. // The allocator to be used to create items in the group.
  80. Allocator allocator_;
  81. // The first thread in the group.
  82. item* first_;
  83. };
  84. } // namespace detail
  85. } // namespace asio
  86. } // namespace boost
  87. #include <boost/asio/detail/pop_options.hpp>
  88. #endif // BOOST_ASIO_DETAIL_THREAD_GROUP_HPP