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



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011