Classes | Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes

cmtk::ThreadPool Class Reference
[cmtkSystem Library]

Class that provides a pool of continuously running threads that can be used for reducing overhead in SMP computations. More...

#include <cmtkThreadPool.h>

Inheritance diagram for cmtk::ThreadPool:
Inheritance graph
[legend]
Collaboration diagram for cmtk::ThreadPool:
Collaboration graph
[legend]

List of all members.

Classes

class  ThreadPoolArg
 Thread function arguments: identify pool and index of thread in it. More...

Public Types

typedef ThreadPool Self
 This class.
typedef SmartPointer< SelfSmartPtr
 Smart pointer.
typedef void(* TaskFunction )(void *const args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t threadCont)
 Task function: this is the interface for the functions called by the pooled threads to do the actual work.

Public Member Functions

 ThreadPool (const size_t nThreads=0)
 Constructor: create a pool of nThreads running threads.
 ~ThreadPool ()
 Destructor: stop all running threads.
size_t GetNumberOfThreads () const
 Return number of threads in the pool.
template<class TParam >
void Run (TaskFunction taskFunction, std::vector< TParam > &taskParameters, const size_t numberOfTasksOverride=0)
 Run actual worker functions through running threads.
void ThreadFunction (const size_t threadIdx)
 This function is run as a thread.

Static Public Member Functions

static SelfGetGlobalThreadPool ()
 Get reference to global thread pool.

Private Member Functions

void StartThreads ()
 Start threads for this pool.
void EndThreads ()
 End threads for this pool.

Private Attributes

ThreadSemaphore m_TaskWaitingSemaphore
 Semaphore to signal running threads when tasks are waiting.
ThreadSemaphore m_ThreadWaitingSemaphore
 Semaphore that threads use to signal when tasks they are ready for the next task.
size_t m_NumberOfTasks
 Total number of tasks to execute.
size_t m_NextTaskIndex
 Index of next available task.
MutexLock m_NextTaskIndexLock
 Lock to ensure exclusive access to the task index counter.
TaskFunction m_TaskFunction
 The current task function.
std::vector< void * > m_TaskParameters
 Task function parameter pointers.
std::vector< Self::ThreadPoolArgm_ThreadArgs
 Thread function parameters.
size_t m_NumberOfThreads
 Number of running threads.
bool m_ThreadsRunning
 Flag whether threads for this pool are running.
bool m_ContinueThreads
 Flag whether threads should continue or terminate.

Detailed Description

Class that provides a pool of continuously running threads that can be used for reducing overhead in SMP computations.

Every instance of this class starts a pool of threads upon initialization, which can later be used to execute arbitrary tasks. The threads are held via a semaphore, which are used to signal the availability of an arbitrary number of tasks. Once the task semaphores have been posted, the calling function waits for the running threads to signal back the same number of completed tasks via a second semaphore.

The main advantages of this thread execution framework are:

1. On platforms with inefficient, slow thread creation and joining (Win32), the use and re-use of a persistent set of threads greatly improves run-time efficiency and reduces overhead.

2. A single computation can be broken into more tasks than there are threads running, i.e., more tasks than there are CPUs available. This allows for load balancing, because tasks that complete faster than others will free the executing thread, which is then available to process the next available task without waiting for any other threads.

This class provides a global thread pool, which can (and should) be shared by all computations in a process. Creating additional thread pool instances should hardly ever be necessary.

To run tasks on the global thread pool, simply create a std::vector that contains a parameter block for each task. The size of the vector also determines the number of tasks to run. For example, the thread parameter could simply be a pointer to the current instance ("this") of a class that acts as the client that requests a parallel computation:

 #include <vector>
 #include <System/cmtkThreadPool.h>

 class ComputationClass
 {
 public:
   typedef ComputationClass Self;

   void ComputeUsingSMP()
   {
     // run approximately four times as many tasks as there are threads (only one task for single thread)
     const size_t numberOfTasks = 4 * ThreadPool::GlobalThreadPool.GetNumberOfThreads() - 3;

     std::vector<Self*> taskParamaters( numberOfTasks, this );
     cmtk::ThreadPool::GlobalThreadPool.Run( ComputeTask, taskParameters );
   }

   void ComputeTask( void *const arg, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t threadCnt )
   {
     Self* Caller = static_cast<Self*>( arg );
     // more things to do for "Caller"
     // taskIdx is the index of this task; taskCnt is the total number of tasks. These two determine what part of the total work must be done.
     // threadIdx is the index of the "physical" thread out of threadCnt threads that are running in this pool. If temporary memory is allocated
     // for this function, then threadIdx can be used to index this temporary storage, thus allowing us to get by with threadCnt many spaces,
     // rather than taskCnt many, which is usuallu much larger.
   }
 };
 *

Definition at line 105 of file cmtkThreadPool.h.


Member Typedef Documentation

This class.

Definition at line 111 of file cmtkThreadPool.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines