Main MRPT website > C++ reference
MRPT logo
threads.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 #ifndef MRPT_SYSTEM_THREADS_H
29 #define MRPT_SYSTEM_THREADS_H
30 
31 #include <mrpt/utils/utils_defs.h>
32 
33 namespace mrpt
34 {
35  namespace system
36  {
37  /** \addtogroup mrpt_thread Threads (in #include <mrpt/system/threads.h>)
38  * \ingroup mrpt_base_grp
39  * @{ */
40 
41  /** This structure contains the information needed to interface the threads API on each platform:
42  * \sa createThread
43  */
45  {
46 #ifdef MRPT_OS_WINDOWS
47  TThreadHandle() : //!< Sets the handle to a predefined value meaning it is uninitialized.
48  hThread(NULL),
49  idThread(0)
50  {
51  }
52 
53  /** Mark the handle as invalid.
54  * \sa isClear
55  */
56  void clear()
57  {
58  idThread = 0;
59  hThread = NULL;
60  }
61  void *hThread; //!< The thread "HANDLE"
62 # if defined(HAVE_OPENTHREAD) // defined(_MSC_VER) && (_MSC_VER>=1400)
63  uintptr_t idThread; //!< The thread ID.
64 # else
65  unsigned long idThread; //!< The thread ID.
66 # endif
67 #endif
68 #if defined(MRPT_OS_LINUX) || defined(MRPT_OS_APPLE)
69  TThreadHandle() : idThread(0) //!< Sets the handle to a predefined value meaning it is uninitialized.
70  {
71  }
72  unsigned long idThread; //!< The thread ID.
73 
74  /** Mark the handle as invalid.
75  * \sa isClear
76  */
77  void clear()
78  {
79  idThread = 0;
80  }
81 #endif
82  /** Returns true if the handle is uninitialized */
83  bool isClear() const { return idThread==0; }
84  };
85 
86  /** The type for cross-platform process (application) priorities.
87  * \sa changeCurrentProcessPriority
88  */
90  ppIdle = 0,
94  };
95 
96  /** The type for cross-platform thread priorities.
97  * \sa changeThreadPriority
98  */
100  tpLowests =-15, // Win32: THREAD_PRIORITY_IDLE
101  tpLower = -2, // Win32: THREAD_PRIORITY_LOWEST
102  tpLow = -1, // Win32: THREAD_PRIORITY_BELOW_NORMAL
103  tpNormal = 0, // Win32: THREAD_PRIORITY_NORMAL
104  tpHigh = 1, // Win32: THREAD_PRIORITY_ABOVE_NORMAL
105  tpHigher = 2, // Win32: THREAD_PRIORITY_HIGHEST
106  tpHighest = 15 // Win32: THREAD_PRIORITY_TIME_CRITICAL
107  };
108 
109  /** Auxiliary classes used internally to MRPT */
110  namespace detail {
111  TThreadHandle BASE_IMPEXP createThreadImpl(void (*func)(void *),void *param);
112  template<typename T> class ThreadCreateFunctor { //T may (and should!) be passed by reference, but mustn't be const.
113  public:
114  void (*func)(T);
115  T obj;
116  inline ThreadCreateFunctor(void (*f)(T),T o):func(f),obj(o) {}
117  inline static void createThreadAux(void *obj) {
118  ThreadCreateFunctor<T> *auxStruct=static_cast<ThreadCreateFunctor<T> *>(obj);
119  auxStruct->func(auxStruct->obj);
120  delete auxStruct;
121  }
122  inline static TThreadHandle createThread(void (*f)(T),T param) {
123  ThreadCreateFunctor *tcs=new ThreadCreateFunctor(f,param);
124  return createThreadImpl(&createThreadAux,static_cast<void *>(tcs));
125  }
126  };
127  // Specialization for T=void*, which is easier to handle:
128  template<> class ThreadCreateFunctor<void *> {
129  public:
130  inline static TThreadHandle createThread(void (*f)(void *),void *param) {
131  return createThreadImpl(f,param);
132  }
133  };
134  // Special case, since T cannot be "void":
136  public:
137  void (*func)(void);
138  ThreadCreateFunctorNoParams( void (*f)(void) ) : func(f) { }
139 
140  inline static void createThreadAux(void *f) {
142  d->func(); // Call the user function.
143  delete d;
144  }
145  inline static TThreadHandle createThread( void (*f)(void) ) {
147  return createThreadImpl(&createThreadAux, static_cast<void*>(dat) );
148  }
149  };
150  // Template for running a non-static method of an object as a thread.
151  template <class CLASS,class PARAM>
153  public:
154  typedef void (CLASS::*objectfunctor_t)(PARAM);
155  CLASS *obj;
157  PARAM p;
158  inline ThreadCreateObjectFunctor(CLASS *o,objectfunctor_t f, PARAM param):obj(o),func(f),p(param) {}
159  inline static void createThreadAux(void *p) {
161  objectfunctor_t f = auxStruct->func;
162  (auxStruct->obj->*f)(auxStruct->p);
163  delete auxStruct;
164  }
165  inline static TThreadHandle createThread(CLASS *o,objectfunctor_t f, PARAM param) {
167  return createThreadImpl(&createThreadAux,static_cast<void *>(tcs));
168  }
169  };
170  // Template for running a non-static method of an object as a thread - no params
171  template <class CLASS>
173  public:
174  typedef void (CLASS::*objectfunctor_t)(void);
175  CLASS *obj;
178  inline static void createThreadAux(void *p) {
180  objectfunctor_t f = auxStruct->func;
181  (auxStruct->obj->*f)();
182  delete auxStruct;
183  }
184  inline static TThreadHandle createThread(CLASS *o,objectfunctor_t f) {
186  return createThreadImpl(&createThreadAux,static_cast<void *>(tcs));
187  }
188  };
189  } // end detail
190 
191  /** Creates a new thread from a function (or static method) with one generic parameter.
192  * This function creates, and start, a new thread running some code given by a function.
193  * The thread function should end by returning as normal.
194  * \param func The function with the code to run in the thread.
195  * \param param The parameter to be passed to the new thread function.
196  * \return A structure that represents the thread (it contains its ID and, in Windows, its HANDLE).
197  * \exception std::exception If the operation fails
198  * \sa createThreadFromObjectMethod, joinThread, changeThreadPriority
199  */
200  template<typename T> inline TThreadHandle createThread(void (*func)(T),T param) {
202  }
203  //! \overload
204  template<typename T> inline TThreadHandle createThreadRef(void (*func)(T&),T& param) {
206  }
207  //! \overload
208  inline TThreadHandle createThread(void (*func)(void)) {
210  }
211 
212  /** Creates a new thread running a non-static method (so it will have access to "this") from another method of the same class - with one generic parameter.
213  * This function creates, and start, a new thread running some code given by a function.
214  * The thread function should end by returning as normal.
215  * Example of usage:
216  *
217  * \code
218  * class MyClass {
219  * public:
220  * void myThread(int n);
221  * void someMethod() {
222  * createThreadFromObjectMethod(this, &MyClass::myThread, 123 );
223  * ....
224  * }
225  * };
226  * \endcode
227  *
228  * \param func The function with the code to run in the thread.
229  * \param param The parameter to be passed to the new thread function.
230  * \return A structure that represents the thread (it contains its ID and, in Windows, its HANDLE).
231  * \exception std::exception If the operation fails
232  * \sa createThread, joinThread, changeThreadPriority
233  */
234  template <typename CLASS,typename PARAM>
235  inline TThreadHandle createThreadFromObjectMethod(CLASS *obj, void (CLASS::*func)(PARAM), PARAM param) {
237  }
238  //! \overload
239  template <typename CLASS,typename PARAM>
240  inline TThreadHandle createThreadFromObjectMethodRef(CLASS *obj, void (CLASS::*func)(PARAM), PARAM &param) {
242  }
243  //! \overload
244  template <typename CLASS>
245  inline TThreadHandle createThreadFromObjectMethod(CLASS *obj, void (CLASS::*func)(void)) {
247  }
248 
249 
250  /** Waits until the given thread ends.
251  * \sa createThread
252  */
253  void BASE_IMPEXP joinThread( const TThreadHandle &threadHandle );
254 
255  /** Returns the ID of the current thread.
256  * \sa getCurrentThreadHandle
257  */
259 
260  /** Returns a handle to the current thread.
261  */
263 
264  /** Explicit close of the current (running) thread.
265  * Do not use normally, it's better just to return from the running thread function.
266  * \sa createThread
267  */
268  void BASE_IMPEXP exitThread() MRPT_NO_THROWS;
269 
270  /** Returns the creation and exit times of the current thread and its CPU time consumed.
271  * \param creationTime The creation time of the thread.
272  * \param exitTime The exit time of the thread, or undefined if it is still running.
273  * \param cpuTime The CPU time consumed by the thread, in seconds.
274  * \exception std::exception If the operation fails
275  * \sa getCurrentThreadHandle, getCurrentThreadId, createThread
276  */
278  time_t &creationTime,
279  time_t &exitTime,
280  double &cpuTime );
281 
282  /** Change the priority of the given thread.
283  * \sa createThread, changeCurrentProcessPriority
284  */
285  void BASE_IMPEXP changeThreadPriority( const TThreadHandle &threadHandle, TThreadPriority priority );
286 
287  /** Terminate a thread, giving it no choice to delete objects, etc (use only as a last resource) */
288  void BASE_IMPEXP terminateThread( TThreadHandle &threadHandle) MRPT_NO_THROWS;
289 
290  /** Change the priority of the given process (it applies to all the threads, plus independent modifiers for each thread).
291  * \sa createThread, changeThreadPriority
292  */
294 
295  /** Return the number of processors ("cores"), or 1 if it cannot be determined.
296  */
297  unsigned int BASE_IMPEXP getNumberOfProcessors();
298 
299  /** An OS-independent method for sending the current thread to "sleep" for a given period of time.
300  * \param time_ms The sleep period, in miliseconds.
301  */
302  void BASE_IMPEXP sleep( int time_ms ) MRPT_NO_THROWS;
303 
304  /** Executes the given command (which may contain a program + arguments), and waits until it finishes.
305  * \return false on any error, true otherwise
306  */
307  bool BASE_IMPEXP launchProcess( const std::string & command );
308 
309  /** @} */
310 
311  } // End of namespace
312 
313 } // End of namespace
314 
315 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013