Choreonoid  1.8
ThreadPool.h
Go to the documentation of this file.
1 
6 #ifndef CNOID_UTIL_THREAD_POOL_H
7 #define CNOID_UTIL_THREAD_POOL_H
8 
9 #include <queue>
10 #include <functional>
11 #include <thread>
12 #include <mutex>
13 #include <condition_variable>
14 
15 namespace cnoid {
16 
18 {
19 private:
20  std::vector<std::thread> threads;
21  std::queue<std::function<void()>> queue;
22  std::mutex mutex;
23  std::condition_variable condition;
24  std::condition_variable finishCondition;
25  int numActiveThreads;
26  bool isDestroying;
27 
28 public:
29  ThreadPool(int size = 1) {
30  numActiveThreads = 0;
31  isDestroying = false;
32  for(int i = 0; i < size; ++i){
33  threads.emplace_back(std::bind(&ThreadPool::run, this));
34  }
35  }
36 
38  {
39  std::lock_guard<std::mutex> guard(mutex);
40  isDestroying = true;
41  condition.notify_all();
42  }
43  // join_all
44  for(auto& thread : threads){
45  if(thread.joinable()){
46  thread.join();
47  }
48  }
49  }
50 
51  int size() const { return threads.size(); }
52 
53  void start(std::function<void()> f) {
54  std::lock_guard<std::mutex> guard(mutex);
55  queue.push(f);
56  condition.notify_one();
57  }
58 
59  void wait(){
60  std::unique_lock<std::mutex> lock(mutex);
61  while(!queue.empty() || numActiveThreads > 0){
62  finishCondition.wait(lock);
63  }
64  }
65 
66  void waitLoop(){
67  while(true){
68  {
69  std::unique_lock<std::mutex> lock(mutex, std::try_to_lock_t());
70  if(lock.owns_lock()){
71  if(queue.empty() && numActiveThreads == 0){
72  break;
73  }
74  }
75  }
76  }
77  }
78 
79  bool isRunning() {
80  std::lock_guard<std::mutex> guard(mutex);
81  return numActiveThreads > 0;
82  }
83 
84 private:
85  void run() {
86  while(true){
87  std::function<void()> f;
88  {
89  std::unique_lock<std::mutex> lock(mutex);
90 
91  while (queue.empty() && !isDestroying){
92  condition.wait(lock);
93  }
94  if(!queue.empty()){
95  f = queue.front();
96  queue.pop();
97  ++numActiveThreads;
98  }
99  }
100  if(f){
101  f();
102  {
103  std::lock_guard<std::mutex> lock(mutex);
104  --numActiveThreads;
105  if(numActiveThreads == 0){
106  finishCondition.notify_all();
107  }
108  }
109  } else {
110  break;
111  }
112  }
113  }
114 };
115 
116 }
117 
118 #endif
cnoid::ThreadPool::isRunning
bool isRunning()
Definition: ThreadPool.h:79
cnoid::ThreadPool::size
int size() const
Definition: ThreadPool.h:51
cnoid
Definition: AbstractSceneLoader.h:11
cnoid::ThreadPool
Definition: ThreadPool.h:17
cnoid::ThreadPool::~ThreadPool
~ThreadPool()
Definition: ThreadPool.h:37
cnoid::ThreadPool::start
void start(std::function< void()> f)
Definition: ThreadPool.h:53
cnoid::ThreadPool::waitLoop
void waitLoop()
Definition: ThreadPool.h:66
cnoid::ThreadPool::wait
void wait()
Definition: ThreadPool.h:59
cnoid::ThreadPool::ThreadPool
ThreadPool(int size=1)
Definition: ThreadPool.h:29