OpenPose  1.7.0
The first real-time multi-person system to jointly detect human body, hand, facial, and foot keypoints
thread.hpp
Go to the documentation of this file.
1 #ifndef OPENPOSE_THREAD_THREAD_HPP
2 #define OPENPOSE_THREAD_THREAD_HPP
3 
4 #include <atomic>
8 
9 namespace op
10 {
11  template<typename TDatums, typename TWorker = std::shared_ptr<Worker<TDatums>>>
12  class Thread
13  {
14  public:
15  explicit Thread(const std::shared_ptr<std::atomic<bool>>& isRunningSharedPtr = nullptr);
16 
17  // Move constructor
18  Thread(Thread&& t);
19 
20  // Move assignment
21  Thread& operator=(Thread&& t);
22 
23  // Destructor
24  virtual ~Thread();
25 
26  void add(const std::vector<std::shared_ptr<SubThread<TDatums, TWorker>>>& subThreads);
27 
28  void add(const std::shared_ptr<SubThread<TDatums, TWorker>>& subThread);
29 
30  void exec(const std::shared_ptr<std::atomic<bool>>& isRunningSharedPtr);
31 
32  void startInThread();
33 
34  void stopAndJoin();
35 
36  inline bool isRunning() const
37  {
38  return *spIsRunning;
39  }
40 
41  private:
42  std::shared_ptr<std::atomic<bool>> spIsRunning;
43  std::vector<std::shared_ptr<SubThread<TDatums, TWorker>>> mSubThreads;
44  std::thread mThread;
45 
46  void initializationOnThread();
47 
48  void threadFunction();
49 
50  void stop();
51 
52  void join();
53 
54  DELETE_COPY(Thread);
55  };
56 }
57 
58 
59 
60 
61 
62 // Implementation
63 namespace op
64 {
65  template<typename TDatums, typename TWorker>
66  Thread<TDatums, TWorker>::Thread(const std::shared_ptr<std::atomic<bool>>& isRunningSharedPtr) :
67  spIsRunning{(isRunningSharedPtr != nullptr ? isRunningSharedPtr : std::make_shared<std::atomic<bool>>(false))}
68  {
69  }
70 
71  template<typename TDatums, typename TWorker>
73  spIsRunning{std::make_shared<std::atomic<bool>>(t.spIsRunning->load())}
74  {
75  std::swap(mSubThreads, t.mSubThreads);
76  std::swap(mThread, t.mThread);
77  }
78 
79  template<typename TDatums, typename TWorker>
81  {
82  std::swap(mSubThreads, t.mSubThreads);
83  std::swap(mThread, t.mThread);
84  spIsRunning = {std::make_shared<std::atomic<bool>>(t.spIsRunning->load())};
85  return *this;
86  }
87 
88  template<typename TDatums, typename TWorker>
90  {
91  try
92  {
93  opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
94  stopAndJoin();
95  opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
96  }
97  catch (const std::exception& e)
98  {
99  errorDestructor(e.what(), __LINE__, __FUNCTION__, __FILE__);
100  }
101  }
102 
103  template<typename TDatums, typename TWorker>
104  void Thread<TDatums, TWorker>::add(const std::vector<std::shared_ptr<SubThread<TDatums, TWorker>>>& subThreads)
105  {
106  for (const auto& subThread : subThreads)
107  mSubThreads.emplace_back(subThread);
108  }
109 
110  template<typename TDatums, typename TWorker>
111  void Thread<TDatums, TWorker>::add(const std::shared_ptr<SubThread<TDatums, TWorker>>& subThread)
112  {
113  add(std::vector<std::shared_ptr<SubThread<TDatums, TWorker>>>{subThread});
114  }
115 
116  template<typename TDatums, typename TWorker>
117  void Thread<TDatums, TWorker>::exec(const std::shared_ptr<std::atomic<bool>>& isRunningSharedPtr)
118  {
119  try
120  {
121  stopAndJoin();
122  spIsRunning = isRunningSharedPtr;
123  *spIsRunning = true;
124  threadFunction();
125  }
126  catch (const std::exception& e)
127  {
128  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
129  }
130  }
131 
132  template<typename TDatums, typename TWorker>
134  {
135  try
136  {
137  opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
138  stopAndJoin();
139  *spIsRunning = true;
140  mThread = {std::thread{&Thread::threadFunction, this}};
141  }
142  catch (const std::exception& e)
143  {
144  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
145  }
146  }
147 
148  template<typename TDatums, typename TWorker>
150  {
151  try
152  {
153  stop();
154  join();
155  }
156  catch (const std::exception& e)
157  {
158  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
159  }
160  }
161 
162  template<typename TDatums, typename TWorker>
164  {
165  try
166  {
167  opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
168  for (auto& subThread : mSubThreads)
169  subThread->initializationOnThread();
170  }
171  catch (const std::exception& e)
172  {
173  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
174  }
175  }
176 
177  template<typename TDatums, typename TWorker>
178  void Thread<TDatums, TWorker>::threadFunction()
179  {
180  try
181  {
182  opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
183  initializationOnThread();
184 
185  opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
186  while (isRunning())
187  {
188  bool allSubThreadsClosed = true;
189  for (auto& subThread : mSubThreads)
190  allSubThreadsClosed &= !subThread->work();
191 
192  if (allSubThreadsClosed)
193  {
194  opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
195  stop();
196  break;
197  }
198  }
199  opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
200  }
201  catch (const std::exception& e)
202  {
203  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
204  }
205  }
206 
207  template<typename TDatums, typename TWorker>
208  void Thread<TDatums, TWorker>::stop()
209  {
210  try
211  {
212  *spIsRunning = false;
213  }
214  catch (const std::exception& e)
215  {
216  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
217  }
218  }
219 
220  template<typename TDatums, typename TWorker>
221  void Thread<TDatums, TWorker>::join()
222  {
223  try
224  {
225  if (mThread.joinable())
226  mThread.join();
227  }
228  catch (const std::exception& e)
229  {
230  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
231  }
232  }
233 
235 }
236 
237 #endif // OPENPOSE_THREAD_THREAD_HPP
void add(const std::vector< std::shared_ptr< SubThread< TDatums, TWorker >>> &subThreads)
Definition: thread.hpp:104
virtual ~Thread()
Definition: thread.hpp:89
Thread & operator=(Thread &&t)
Definition: thread.hpp:80
bool isRunning() const
Definition: thread.hpp:36
void stopAndJoin()
Definition: thread.hpp:149
Thread(const std::shared_ptr< std::atomic< bool >> &isRunningSharedPtr=nullptr)
Definition: thread.hpp:66
void startInThread()
Definition: thread.hpp:133
void exec(const std::shared_ptr< std::atomic< bool >> &isRunningSharedPtr)
Definition: thread.hpp:117
COMPILE_TEMPLATE_DATUM(WPoseTriangulation)
OP_API void error(const std::string &message, const int line=-1, const std::string &function="", const std::string &file="")
OP_API void errorDestructor(const std::string &message, const int line=-1, const std::string &function="", const std::string &file="")
OP_API void opLog(const std::string &message, const Priority priority=Priority::Max, const int line=-1, const std::string &function="", const std::string &file="")