XNetwork 1.7.8
Loading...
Searching...
No Matches
thread_pool.hpp
Go to the documentation of this file.
1#pragma once
2
23#include <condition_variable>
24#include <functional>
25#include <future>
26#include <memory>
27#include <mutex>
28#include <queue>
29#include <thread>
30#include <type_traits>
31#include <utility>
32
33namespace xnetwork {
34
43 public:
48 explicit thread_pool(size_t num_threads = std::thread::hardware_concurrency())
49 : stop_(false) {
50 if (num_threads == 0) {
51 num_threads = 1;
52 }
53 workers_.reserve(num_threads);
54 for (size_t i = 0; i < num_threads; ++i) {
55 workers_.emplace_back([this] { worker_loop(); });
56 }
57 }
58
60 {
61 std::lock_guard<std::mutex> lock(queue_mutex_);
62 stop_ = true;
63 }
64 condition_.notify_all();
65 for (auto& w : workers_) {
66 if (w.joinable()) {
67 w.join();
68 }
69 }
70 }
71
72 thread_pool(const thread_pool&) = delete;
76
84 template <typename F> auto enqueue(F&& task)
85 -> std::future<std::invoke_result_t<std::decay_t<F>>> {
86 using return_type = std::invoke_result_t<std::decay_t<F>>;
87
88 auto packaged
89 = std::make_shared<std::packaged_task<return_type()>>(std::forward<F>(task));
90
91 auto future = packaged->get_future();
92 {
93 std::lock_guard<std::mutex> lock(queue_mutex_);
94 if (stop_) {
95 throw std::runtime_error("enqueue on stopped thread_pool");
96 }
97 tasks_.emplace([packaged]() { (*packaged)(); });
98 }
99 condition_.notify_one();
100 return future;
101 }
102
103 private:
104 void worker_loop() {
105 while (true) {
106 std::function<void()> task;
107 {
108 std::unique_lock<std::mutex> lock(queue_mutex_);
109 condition_.wait(lock, [this] { return stop_ || !tasks_.empty(); });
110 if (stop_ && tasks_.empty()) {
111 return;
112 }
113 task = std::move(tasks_.front());
114 tasks_.pop();
115 }
116 task();
117 }
118 }
119
120 std::vector<std::thread> workers_;
121 std::queue<std::function<void()>> tasks_;
122 std::mutex queue_mutex_;
123 std::condition_variable condition_;
124 bool stop_;
125 };
126
127} // namespace xnetwork
Read-only map of maps of maps (view into a dict-of-dict-of-dict structure)
Definition coreviews.hpp:109
Command pattern: tasks are encapsulated as command objects (std::function<void()>) placed in a shared...
Definition thread_pool.hpp:42
~thread_pool()
Definition thread_pool.hpp:59
thread_pool(size_t num_threads=std::thread::hardware_concurrency())
Definition thread_pool.hpp:48
thread_pool(thread_pool &&)=delete
thread_pool & operator=(const thread_pool &)=delete
thread_pool(const thread_pool &)=delete
thread_pool & operator=(thread_pool &&)=delete
auto enqueue(F &&task) -> std::future< std::invoke_result_t< std::decay_t< F > > >
Definition thread_pool.hpp:84
Definition digraphs.hpp:24