35 #include <condition_variable> 38 #include <unordered_set> 51 template <
typename Closure>
57 std::optional<Closure> task;
95 template <
typename... ArgsT>
105 size_t num_tasks()
const;
117 bool _exiting {
false};
120 void _spawn(
unsigned);
124 template <
typename Closure>
130 template <
typename Closure>
136 template <
typename Closure>
142 template <
typename Closure>
144 return _tasks.size();
148 template <
typename Closure>
150 return _threads.size();
154 template <
typename Closure>
165 for(
auto w : _idlers){
167 w->task = std::nullopt;
173 for(
auto& t : _threads){
182 template <
typename Closure>
187 for(
size_t i=0; i<N; ++i){
189 _threads.emplace_back([
this] () ->
void {
200 _idlers.push_back(&w);
210 w.task = std::nullopt;
215 Closure t{std::move(_tasks.back())};
228 template <
typename Closure>
229 template <
typename... ArgsT>
234 Closure{std::forward<ArgsT>(args)...}();
238 std::scoped_lock lock(_mutex);
240 _tasks.emplace_back(std::forward<ArgsT>(args)...);
243 Worker* w = _idlers.back();
246 w->task.emplace(std::forward<ArgsT>(args)...);
254 template <
typename Closure>
266 std::scoped_lock lock(_mutex);
268 std::move(tasks.begin(), tasks.end(), std::back_inserter(_tasks));
272 while(consumed != tasks.size() && !_idlers.empty()) {
273 Worker* w = _idlers.back();
276 w->task.emplace(std::move(tasks[consumed++]));
280 if(consumed == tasks.size())
return ;
281 _tasks.reserve(_tasks.size() + tasks.size() - consumed);
282 std::move(tasks.begin()+consumed, tasks.end(), std::back_inserter(_tasks));
size_t num_workers() const
queries the number of worker threads
Definition: proactive_threadpool.hpp:149
~ProactiveThreadpool()
destructs the executor
Definition: proactive_threadpool.hpp:131
ProactiveThreadpool(unsigned N)
constructs the executor with a given number of worker threads
Definition: proactive_threadpool.hpp:125
Executor that implements a centralized task queue with a proactive execution strategy.
Definition: proactive_threadpool.hpp:52
Definition: taskflow.hpp:6
void emplace(ArgsT &&... args)
constructs the closure in place in the executor
Definition: proactive_threadpool.hpp:230
void batch(std::vector< Closure > &&closures)
moves a batch of closures to the executor
Definition: proactive_threadpool.hpp:255
bool is_owner() const
queries if the caller is the owner of the executor
Definition: proactive_threadpool.hpp:137