10 #ifndef THREADPOOL2_HPP_
11 #define THREADPOOL2_HPP_
20 #include <condition_variable>
32 std::vector< std::thread > workers;
33 std::atomic<int> _running;
35 std::queue<std::function<void(T&)> > _tasks;
38 std::mutex queue_mutex;
39 std::condition_variable condition;
41 std::mutex _returned_mutex;
42 std::condition_variable _returned;
50 template<
class F,
class... Args>
51 void addTask(F&& f, Args&&... args);
58 return _running.load();
66 : workers(), _running(0), _tasks(), queue_mutex(), condition(), _returned_mutex(), _returned(), _stop(false)
68 for(
size_t i = 0;i<threads;++i)
71 [
this] (
const T &local_data)
73 std::function<void(T&)> task;
78 std::unique_lock<std::mutex> lock(this->queue_mutex);
79 while(!this->_stop && _tasks.empty())
80 this->condition.wait(lock);
81 if(this->_stop && _tasks.empty())
83 task = _tasks.front();
88 std::unique_lock<std::mutex> lock(_returned_mutex);
91 _returned.notify_all();
101 template<
class F,
class... Args>
106 throw std::runtime_error(
"enqueue on stopped ThreadPool");
108 std::unique_lock<std::mutex> lock(_returned_mutex);
109 while(_running.load()>workers.size()*1.5)
110 this->_returned.wait(lock);
112 auto task = std::function<void(T&)> (
113 std::bind(std::forward<F>(f), std::forward<Args>(args)..., std::placeholders::_1)
117 std::unique_lock<std::mutex> lock(queue_mutex);
120 condition.notify_all();
128 std::unique_lock<std::mutex> lock(queue_mutex);
131 condition.notify_all();
132 for(
size_t i = 0; i<workers.size(); ++i)
149 std::unique_lock<std::mutex> lock(_returned_mutex);
150 while(_running.load()!=0)
151 this->_returned.wait(lock);