AnCH Framework  0.1
Another C++ Hack Framework
threadPool.hpp
1 /*
2  ANCH Framework: ANother C++ Hack is a C++ framework based on C++11 standard
3  Copyright (C) 2012 Vincent Lachenal
4 
5  This file is part of ANCH Framework.
6 
7  ANCH Framework is free software: you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  ANCH Framework is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with ANCH Framework. If not, see <http://www.gnu.org/licenses/>.
19 */
20 #ifndef _ANCH_THREAD_POOL_H_
21 #define _ANCH_THREAD_POOL_H_
22 
23 #include <functional>
24 #include <thread>
25 #include <mutex>
26 #include <queue>
27 #include <chrono>
28 #include <atomic>
29 
30 namespace anch {
31 
45  class ThreadPool {
46  // Attributes +
47  private:
49  std::queue<std::function<void()> > _threads;
50 
52  std::mutex _mutex;
53 
55  unsigned int _maxThreads;
56 
58  std::atomic<unsigned int> _available;
59 
61  bool _running;
62  // Attributes -
63 
64  // Constructors +
65  public:
71  ThreadPool(unsigned int maxThreads = 0):
72  _threads(),
73  _mutex(),
74  _available(0),
75  _running(false) {
76  if(maxThreads == 0) {
77  _maxThreads = std::thread::hardware_concurrency();
78  if(_maxThreads == 0) { // Check if maximum number of thread is at least 1 to execute at least one thread
79  _maxThreads = 1;
80  }
81  } else {
82  _maxThreads = maxThreads;
83  }
84  }
85  // Constructors -
86 
87  // Destructor +
88  public:
92  virtual ~ThreadPool() {
93  _mutex.lock();
94  _running = false;
95  while(!_threads.empty()) {
96  _threads.pop();
97  }
98  _mutex.unlock();
99  }
100  // Destructor -
101 
102  // Methods +
103  public:
107  void start() {
108  std::lock_guard<std::mutex> lock(_mutex);
109  if(!_running) {
110  _available.store(_maxThreads);
111  _running = true;
112  // Check if there is some threads to proceed +
113  while(_available.load() > 0 && !_threads.empty()) {
114  _available--;
115  std::thread exec(&ThreadPool::execute, this, _threads.front());
116  exec.detach();
117  _threads.pop();
118  }
119  // Check if there is some threads to proceed -
120  }
121  }
122 
126  void stop() {
127  std::lock_guard<std::mutex> lock(_mutex);
128  if(_running) {
129  _running = false;
130  // Wait for alive threads
131  while(_available.load() != _maxThreads) {
132  std::this_thread::sleep_for(std::chrono::milliseconds(50));
133  }
134  }
135  }
136 
143  template<typename Func, typename... Args>
144  void add(Func function, Args... args) {
145  std::lock_guard<std::mutex> lock(_mutex);
146  if(_running) {
147  if(_available.load() > 0 && _threads.size() < _maxThreads) {
148  _available--;
149  std::thread exec(&ThreadPool::execute, this, static_cast<std::function<void()> >(std::bind(function, args...)));
150  exec.detach();
151  } else {
152  _threads.push(std::bind(function, args...));
153  }
154 
155  } else {
156  _threads.push(std::bind(function, args...));
157  }
158  }
159 
160  private:
166  void execute(std::function<void()> func) {
167  try {
168  func();
169  _available++;
170  } catch(...) {
171  _available++;
172  }
173  _mutex.lock();
174  if(_running && _available.load() > 0 && !_threads.empty()) {
175  _available--;
176  std::thread exec(&ThreadPool::execute, this, _threads.front());
177  exec.detach();
178  _threads.pop();
179  }
180  _mutex.unlock();
181  }
182  // Methods -
183 
184  };
185 
186 }
187 
188 #endif // _ANCH_THREAD_POOL_H_
ThreadPool(unsigned int maxThreads=0)
Definition: threadPool.hpp:71
Thread pool utility class.
Definition: threadPool.hpp:45
AnCH framework base namespace.
Definition: base64.hpp:28
virtual ~ThreadPool()
Definition: threadPool.hpp:92
void start()
Definition: threadPool.hpp:107
void add(Func function, Args...args)
Definition: threadPool.hpp:144
void stop()
Definition: threadPool.hpp:126