Lunchbox  1.16.0
Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.
threadPool.ipp
1 /* Copyright (c) 2016-2017, Mohamed-Ghaith Kaabi <mohamedghaith.kaabi@gmail.com>
2  *
3  * This library is free software; you can redistribute it and/or modify it under
4  * the terms of the GNU Lesser General Public License version 2.1 as published
5  * by the Free Software Foundation.
6  *
7  * This library is distributed in the hope that it will be useful, but WITHOUT
8  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
10  * details.
11  *
12  * You should have received a copy of the GNU Lesser General Public License
13  * along with this library; if not, write to the Free Software Foundation, Inc.,
14  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15  */
16 
17 namespace lunchbox
18 {
19 ThreadPool::ThreadPool(const size_t size)
20  : _stop(false)
21 {
22  for (size_t i = 0; i < size; ++i)
23  _threads.emplace_back([this] { this->work(); });
24 }
25 
27 {
28  {
29  std::unique_lock<std::mutex> lock(_mutex);
30  _stop = true;
31  _condition.notify_all();
32  }
33  joinAll();
34 }
35 
36 size_t ThreadPool::getSize() const
37 {
38  return _threads.size();
39 }
40 
41 template <typename F>
42 std::future<typename std::result_of<F()>::type> ThreadPool::post(F&& f)
43 {
44  using ReturnType = typename std::result_of<F()>::type;
45 
46  auto task =
47  std::make_shared<std::packaged_task<ReturnType()> >(std::forward<F>(f));
48 
49  auto res = task->get_future();
50  {
51  std::unique_lock<std::mutex> lock(_mutex);
52  _tasks.emplace([task]() { (*task)(); });
53  }
54  _condition.notify_one();
55  return res;
56 }
57 
58 template <typename F>
60 {
61  {
62  std::unique_lock<std::mutex> lock(_mutex);
63  _tasks.emplace(f);
64  }
65  _condition.notify_one();
66 }
67 
69 {
70  std::unique_lock<std::mutex> lock(_mutex);
71  return !_tasks.empty();
72 }
73 
74 void ThreadPool::joinAll()
75 {
76  for (auto& thread : _threads)
77  thread.join();
78 }
79 
80 void ThreadPool::work()
81 {
82  for (;;)
83  {
84  std::function<void()> task;
85  {
86  std::unique_lock<std::mutex> lock(_mutex);
87  _condition.wait(lock, [this] { return _stop || !_tasks.empty(); });
88  if (_stop)
89  return;
90  task = std::move(_tasks.front());
91  _tasks.pop();
92  }
93  task();
94  }
95 }
96 }
size_t getSize() const
Definition: threadPool.ipp:36
bool hasPendingJobs() const
Definition: threadPool.ipp:68
~ThreadPool()
Destroy this thread pool.
Definition: threadPool.ipp:26
std::future< typename std::result_of< F()>::type > post(F &&f)
Post a new task in the thread pool.
Definition: threadPool.ipp:42
ThreadPool(const size_t size=std::max(1u, std::thread::hardware_concurrency()))
Construct a ThreadPool.
Definition: threadPool.ipp:19
void postDetached(F &&f)
Post a detached task in the thread pool.
Definition: threadPool.ipp:59
Abstraction layer and common utilities for multi-threaded programming.
Definition: algorithm.h:29