ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkThreadPool.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkThreadPool_h
19 #define itkThreadPool_h
20 
21 #include "itkConfigure.h"
22 #include "itkIntTypes.h"
23 
24 #include <deque>
25 #include <functional>
26 #include <future>
27 #include <condition_variable>
28 #include <thread>
29 
30 #include "itkObject.h"
31 #include "itkObjectFactory.h"
32 #include "itkSingletonMacro.h"
33 
34 
35 namespace itk
36 {
37 
53 struct ThreadPoolGlobals;
54 
55 class ITKCommon_EXPORT ThreadPool : public Object
56 {
57 public:
58  ITK_DISALLOW_COPY_AND_ASSIGN(ThreadPool);
59 
61  using Self = ThreadPool;
62  using Superclass = Object;
65 
67  itkTypeMacro(ThreadPool, Object);
68 
70  static Pointer New();
71 
73  static Pointer GetInstance();
74 
81  template< class Function, class... Arguments >
82  auto
83  AddWork( Function&& function, Arguments&&... arguments )
84  -> std::future< typename std::result_of< Function( Arguments... ) >::type >
85  {
86  using return_type = typename std::result_of< Function( Arguments... ) >::type;
88 
89  auto task = std::make_shared< std::packaged_task< return_type() > >(
90  std::bind( std::forward< Function >( function ), std::forward< Arguments >( arguments )... ) );
91 
92  std::future< return_type > res = task->get_future();
93  {
94  std::unique_lock< std::mutex > lock( this->GetMutex() );
95  m_WorkQueue.emplace_back( [task]() { ( *task )(); } );
96  }
97  m_Condition.notify_one();
98  return res;
99  }
100 
102  void AddThreads(ThreadIdType count);
103 
105  {
106  return static_cast< ThreadIdType >( m_Threads.size() );
107  }
108 
110  int GetNumberOfCurrentlyIdleThreads() const;
111 
116  static bool GetDoNotWaitForThreads();
117  static void SetDoNotWaitForThreads(bool doNotWaitForThreads);
119 
120 protected:
121 
122  /* We need access to the mutex in AddWork, and the variable is only
123  * visible in .cxx file, so this method returns it. */
124  std::mutex& GetMutex();
125 
126  ThreadPool();
127  ~ThreadPool() override;
128 
129 private:
130 
132  itkGetGlobalDeclarationMacro(ThreadPoolGlobals, PimplGlobals);
133 
137  std::deque< std::function< void() > > m_WorkQueue;
138 
141  std::condition_variable m_Condition;
142 
145  std::vector< std::thread > m_Threads;
146 
147  /* Has destruction started? */
148  bool m_Stopping{ false };
149 
151  static ThreadPoolGlobals * m_PimplGlobals;
152 
154  static void ThreadExecute();
155 };
156 
157 }
158 #endif
Light weight base class for most itk classes.
std::condition_variable m_Condition
std::deque< std::function< void() > > m_WorkQueue
#define itkGetGlobalDeclarationMacro(Type, VarName)
std::vector< std::thread > m_Threads
ThreadIdType GetMaximumNumberOfThreads() const
unsigned int ThreadIdType
Definition: itkIntTypes.h:99
Thread pool maintains a constant number of threads.
Definition: itkThreadPool.h:55
Base class for most ITK classes.
Definition: itkObject.h:60
static ThreadPoolGlobals * m_PimplGlobals