Main MRPT website > C++ reference
MRPT logo

threads.h

Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                   http://mrpt.sourceforge.net/                            |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef  MRPT_SYSTEM_THREADS_H
00029 #define  MRPT_SYSTEM_THREADS_H
00030 
00031 #include <mrpt/utils/utils_defs.h>
00032 
00033 namespace mrpt
00034 {
00035         namespace system
00036         {
00037                 /** @name Threads
00038                 @{ */
00039 
00040                 /** This structure contains the information needed to interface the threads API on each platform:
00041                   * \sa createThread
00042                   */
00043                 struct TThreadHandle
00044                 {
00045 #ifdef MRPT_OS_WINDOWS
00046                         TThreadHandle()  :  //!< Sets the handle to a predefined value meaning it is uninitialized.
00047                                 hThread(NULL),
00048                                 idThread(0)
00049                         {
00050                         }
00051 
00052                         /** Mark the handle as invalid.
00053                           * \sa isClear
00054                           */
00055                         void clear()
00056                         {
00057                                 idThread = 0;
00058                                 hThread  = NULL;
00059                         }
00060                         void                    *hThread;               //!< The thread "HANDLE"
00061 # if  defined(HAVE_OPENTHREAD) // defined(_MSC_VER) && (_MSC_VER>=1400)
00062                         uintptr_t               idThread;               //!< The thread ID.
00063 # else
00064                         unsigned long   idThread;               //!< The thread ID.
00065 # endif
00066 #endif
00067 #if defined(MRPT_OS_LINUX) || defined(MRPT_OS_APPLE)
00068                         TThreadHandle() : idThread(0)  //!< Sets the handle to a predefined value meaning it is uninitialized.
00069                         {
00070                         }
00071                         unsigned long   idThread;               //!< The thread ID.
00072 
00073                         /** Mark the handle as invalid.
00074                           * \sa isClear
00075                           */
00076                         void clear()
00077                         {
00078                                 idThread = 0;
00079                         }
00080 #endif
00081                         /** Returns true if the handle is uninitialized */
00082                         bool isClear() const { return idThread==0; }
00083                 };
00084 
00085                 /**  The type for cross-platform process (application) priorities.
00086                   * \sa changeCurrentProcessPriority
00087                   */
00088                 enum TProcessPriority {
00089                         ppIdle = 0,
00090                         ppNormal,
00091                         ppHigh,
00092                         ppVeryHigh
00093                 };
00094 
00095                 /**  The type for cross-platform thread priorities.
00096                   * \sa changeThreadPriority
00097                   */
00098                 enum TThreadPriority {
00099                         tpLowests =-15, // Win32: THREAD_PRIORITY_IDLE
00100                         tpLower = -2,   // Win32: THREAD_PRIORITY_LOWEST
00101                         tpLow = -1,             // Win32: THREAD_PRIORITY_BELOW_NORMAL
00102                         tpNormal = 0,   // Win32: THREAD_PRIORITY_NORMAL
00103                         tpHigh = 1,     // Win32: THREAD_PRIORITY_ABOVE_NORMAL
00104                         tpHigher = 2,   // Win32: THREAD_PRIORITY_HIGHEST
00105                         tpHighest = 15  // Win32: THREAD_PRIORITY_TIME_CRITICAL
00106                 };
00107 
00108                 /** Auxiliary classes used internally to MRPT */
00109                 namespace detail        {
00110                         TThreadHandle BASE_IMPEXP createThreadImpl(void (*func)(void *),void *param);
00111                         template<typename T> class ThreadCreateFunctor  {       //T may (and should!) be passed by reference, but mustn't be const.
00112                         public:
00113                                 void (*func)(T);
00114                                 T obj;
00115                                 inline ThreadCreateFunctor(void (*f)(T),T o):func(f),obj(o)     {}
00116                                 inline static void createThreadAux(void *obj)   {
00117                                         ThreadCreateFunctor<T> *auxStruct=static_cast<ThreadCreateFunctor<T> *>(obj);
00118                                         auxStruct->func(auxStruct->obj);
00119                                         delete auxStruct;
00120                                 }
00121                                 inline static TThreadHandle createThread(void (*f)(T),T param)  {
00122                                         ThreadCreateFunctor *tcs=new ThreadCreateFunctor(f,param);
00123                                         return createThreadImpl(&createThreadAux,static_cast<void *>(tcs));
00124                                 }
00125                         };
00126                         // Specialization for T=void*, which is easier to handle:
00127                         template<> class ThreadCreateFunctor<void *>    {
00128                         public:
00129                                 inline static TThreadHandle createThread(void (*f)(void *),void *param) {
00130                                         return createThreadImpl(f,param);
00131                                 }
00132                         };
00133                         // Special case, since T cannot be "void":
00134                         class ThreadCreateFunctorNoParams       {
00135                         public:
00136                                 void (*func)(void);
00137                                 ThreadCreateFunctorNoParams( void (*f)(void) ) : func(f) { }
00138 
00139                                 inline static void createThreadAux(void *f)     {
00140                                         ThreadCreateFunctorNoParams *d=static_cast<ThreadCreateFunctorNoParams*>(f);
00141                                         d->func(); // Call the user function.
00142                                         delete d;
00143                                 }
00144                                 inline static TThreadHandle createThread( void (*f)(void) )     {
00145                                         ThreadCreateFunctorNoParams *dat = new ThreadCreateFunctorNoParams(f);
00146                                         return createThreadImpl(&createThreadAux, static_cast<void*>(dat) );
00147                                 }
00148                         };
00149                         // Template for running a non-static method of an object as a thread.
00150                         template <class CLASS,class PARAM>
00151                         class ThreadCreateObjectFunctor {
00152                         public:
00153                                 typedef void (CLASS::*objectfunctor_t)(PARAM);
00154                                 CLASS *obj;
00155                                 objectfunctor_t func;
00156                                 PARAM p;
00157                                 inline ThreadCreateObjectFunctor(CLASS *o,objectfunctor_t f, PARAM param):obj(o),func(f),p(param) {}
00158                                 inline static void createThreadAux(void *p)     {
00159                                         ThreadCreateObjectFunctor<CLASS,PARAM> *auxStruct=static_cast<ThreadCreateObjectFunctor<CLASS,PARAM>*>(p);
00160                                         objectfunctor_t f = auxStruct->func;
00161                                         (auxStruct->obj->*f)(auxStruct->p);
00162                                         delete auxStruct;
00163                                 }
00164                                 inline static TThreadHandle createThread(CLASS *o,objectfunctor_t f, PARAM param)       {
00165                                         ThreadCreateObjectFunctor *tcs=new ThreadCreateObjectFunctor(o,f,param);
00166                                         return createThreadImpl(&createThreadAux,static_cast<void *>(tcs));
00167                                 }
00168                         };
00169                         // Template for running a non-static method of an object as a thread - no params
00170                         template <class CLASS>
00171                         class ThreadCreateObjectFunctorNoParams {
00172                         public:
00173                                 typedef void (CLASS::*objectfunctor_t)(void);
00174                                 CLASS *obj;
00175                                 objectfunctor_t func;
00176                                 inline ThreadCreateObjectFunctorNoParams(CLASS *o,objectfunctor_t f):obj(o),func(f) {}
00177                                 inline static void createThreadAux(void *p)     {
00178                                         ThreadCreateObjectFunctorNoParams<CLASS> *auxStruct=static_cast<ThreadCreateObjectFunctorNoParams<CLASS>*>(p);
00179                                         objectfunctor_t f = auxStruct->func;
00180                                         (auxStruct->obj->*f)();
00181                                         delete auxStruct;
00182                                 }
00183                                 inline static TThreadHandle createThread(CLASS *o,objectfunctor_t f)    {
00184                                         ThreadCreateObjectFunctorNoParams *tcs=new ThreadCreateObjectFunctorNoParams(o,f);
00185                                         return createThreadImpl(&createThreadAux,static_cast<void *>(tcs));
00186                                 }
00187                         };
00188                 } // end detail
00189 
00190         /** Creates a new thread from a function (or static method) with one generic parameter.
00191           *  This function creates, and start, a new thread running some code given by a function.
00192           *  The thread function should end by returning as normal.
00193           * \param func The function with the code to run in the thread.
00194           * \param param The parameter to be passed to the new thread function.
00195           * \return A structure that represents the thread (it contains its ID and, in Windows, its HANDLE).
00196           * \exception std::exception If the operation fails
00197           * \sa createThreadFromObjectMethod, joinThread, changeThreadPriority
00198           */
00199                 template<typename T> inline TThreadHandle createThread(void (*func)(T),T param) {
00200                         return detail::ThreadCreateFunctor<T>::createThread(func,param);
00201                 }
00202         //! \overload
00203                 template<typename T> inline TThreadHandle createThreadRef(void (*func)(T&),T& param)    {
00204                         return detail::ThreadCreateFunctor<T&>::createThread(func,param);
00205                 }
00206         //! \overload
00207                 inline TThreadHandle createThread(void (*func)(void))   {
00208                         return detail::ThreadCreateFunctorNoParams::createThread(func);
00209                 }
00210 
00211         /** 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.
00212           *  This function creates, and start, a new thread running some code given by a function.
00213           *  The thread function should end by returning as normal.
00214           *  Example of usage:
00215           *
00216           *  \code
00217           *    class MyClass {
00218           *    public:
00219           *      void myThread(int n);
00220           *      void someMethod() {
00221           *         createThreadFromObjectMethod(this, &MyClass::myThread, 123 );
00222           *         ....
00223           *      }
00224           *    };
00225           *  \endcode
00226           *
00227           * \param func The function with the code to run in the thread.
00228           * \param param The parameter to be passed to the new thread function.
00229           * \return A structure that represents the thread (it contains its ID and, in Windows, its HANDLE).
00230           * \exception std::exception If the operation fails
00231           * \sa createThread, joinThread, changeThreadPriority
00232           */
00233                 template <typename CLASS,typename PARAM>
00234                 inline TThreadHandle createThreadFromObjectMethod(CLASS *obj, void (CLASS::*func)(PARAM), PARAM param)  {
00235                         return detail::ThreadCreateObjectFunctor<CLASS,PARAM>::createThread(obj,func,param);
00236                 }
00237         //! \overload
00238                 template <typename CLASS,typename PARAM>
00239                 inline TThreadHandle createThreadFromObjectMethodRef(CLASS *obj, void (CLASS::*func)(PARAM), PARAM &param)      {
00240                         return detail::ThreadCreateObjectFunctor<CLASS,PARAM&>::createThread(obj,func,param);
00241                 }
00242         //! \overload
00243                 template <typename CLASS>
00244                 inline TThreadHandle createThreadFromObjectMethod(CLASS *obj, void (CLASS::*func)(void))        {
00245                         return detail::ThreadCreateObjectFunctorNoParams<CLASS>::createThread(obj,func);
00246                 }
00247 
00248 
00249         /** Waits until the given thread ends.
00250           * \sa createThread
00251           */
00252         void BASE_IMPEXP joinThread( const TThreadHandle &threadHandle );
00253 
00254         /** Returns the ID of the current thread.
00255           * \sa getCurrentThreadHandle
00256           */
00257         unsigned long BASE_IMPEXP getCurrentThreadId() MRPT_NO_THROWS;
00258 
00259         /** Returns a handle to the current thread.
00260           */
00261         TThreadHandle BASE_IMPEXP getCurrentThreadHandle() MRPT_NO_THROWS;
00262 
00263         /** Explicit close of the current (running) thread.
00264           *  Do not use normally, it's better just to return from the running thread function.
00265           * \sa createThread
00266           */
00267         void BASE_IMPEXP exitThread() MRPT_NO_THROWS;
00268 
00269                 /** Returns the creation and exit times of the current thread and its CPU time consumed.
00270                   * \param creationTime The creation time of the thread.
00271                   * \param exitTime The exit time of the thread, or undefined if it is still running.
00272                   * \param cpuTime The CPU time consumed by the thread, in seconds.
00273           * \exception std::exception If the operation fails
00274           * \sa getCurrentThreadHandle, getCurrentThreadId, createThread
00275           */
00276                 void BASE_IMPEXP getCurrentThreadTimes(
00277                         time_t                  &creationTime,
00278                         time_t                  &exitTime,
00279                         double                  &cpuTime );
00280 
00281         /** Change the priority of the given thread.
00282           * \sa createThread, changeCurrentProcessPriority
00283           */
00284         void BASE_IMPEXP changeThreadPriority( const TThreadHandle &threadHandle, TThreadPriority priority );
00285 
00286                 /** Terminate a thread, giving it no choice to delete objects, etc (use only as a last resource) */
00287                 void BASE_IMPEXP terminateThread( TThreadHandle &threadHandle) MRPT_NO_THROWS;
00288 
00289         /** Change the priority of the given process (it applies to all the threads, plus independent modifiers for each thread).
00290           * \sa createThread, changeThreadPriority
00291           */
00292         void BASE_IMPEXP changeCurrentProcessPriority( TProcessPriority priority );
00293 
00294         /** Return the number of processors ("cores"), or 1 if it cannot be determined.
00295           */
00296         unsigned int BASE_IMPEXP getNumberOfProcessors();
00297 
00298                 /** An OS-independent method for sending the current thread to "sleep" for a given period of time.
00299                   * \param time_ms The sleep period, in miliseconds.
00300                   */
00301                 void BASE_IMPEXP sleep( int time_ms ) MRPT_NO_THROWS;
00302 
00303                 /** Executes the given command (which may contain a program + arguments), and waits until it finishes.
00304                   * \return false on any error, true otherwise
00305                   */
00306                 bool BASE_IMPEXP  launchProcess( const std::string & command );
00307 
00308                 /**  @} */
00309 
00310         } // End of namespace
00311 
00312 } // End of namespace
00313 
00314 #endif



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:16:28 UTC 2011