Sourceforge.net - The VCF's Project Host
   The VCF Website Home   |   Online Discussion Forums   |   Sourceforge.net Project Page   

VCF::ThreadPool Class Reference

A simple class for thread pooling. More...

#include <ThreadPool.h>

List of all members.

Public Member Functions

 ThreadPool (size_t poolSize)
 Creates a thread pool instance.
uint32 getThreadCount () const
 Returns the number of threads associated with this pool.
void initPool ()
 Initializes the pool.
void start ()
 Starts the pool's threads running.
void stop ()
 Stop the pool from running.
void wait ()
 Waits for all work to be finished.
void wait (uint32 timeoutInMilliseconds)
 Waits for all work to be finished.
void postWork (Runnable *workToDo)
 This method adds the new work item to the queue of work items and returns immediately.
RunnablewaitForWork ()
 Call this method to wait until new work has arrived.

Public Attributes

std::vector< PoolThread * > threads_
 A vector of threads that are being run by the pool.
std::deque< Runnable * > work_
 A queue of work to be performed.
Mutex workMtx_
 The mutext to protect access to the work_, and stopped_ variables.
Condition workAvailable_
 The condition used to indicate whether or not there is work available.
Mutex cdtnMtx_
Condition waitForWorkDone_
 The condition used to indicate that all the work has been completed/processed.
Mutex waitForWorkDoneMtx_
bool stopped_
 The variable used to tell if the pool is being shut down as a result of the ThreadPool::stop() method being called.


Detailed Description

A simple class for thread pooling.

This class allows you to specify the number of threads to be run in the pool. The pool works by allowing you to post "work" to it in the form of a valid Runnable instance, and then having one of the threads run this "work" item when the thread is available for work. The work item is executed by having the pool thread call the item's run() method. After the item's run() method is called the thread deletes the item, and waits for the pool to give a new item of work to run. You can wait for the pool's threads to finish running their work by using the ThreadPool::wait() method. You can start or stop the pool at will. The pool is meant to be easy to use, for example:

class SomeWork : public Runnable {
public:
    virtual bool run() {
        printf( "SomeWork %p was run!\n", this );       
        return true;
    }
    virtual void stop(){}
};

int main( int argc, char** argv ){

    FoundationKit::init( argc, argv );
    
    {
        ThreadPool pool(3);
        pool.start();
        
        pool.postWork( new SomeWork() );
        pool.postWork( new SomeWork() );
        pool.postWork( new SomeWork() );
        pool.postWork( new SomeWork() );
        
        
        pool.wait(  );
        pool.stop();
    }

    FoundationKit::terminate();
    return 0;
}

See also:
Runnable

PoolThread


Constructor & Destructor Documentation

VCF::ThreadPool::ThreadPool size_t  poolSize  )  [inline]
 

Creates a thread pool instance.

When called the pool is initialized with the specified number of threads


Member Function Documentation

uint32 VCF::ThreadPool::getThreadCount  )  const [inline]
 

Returns the number of threads associated with this pool.

void VCF::ThreadPool::initPool  )  [inline]
 

Initializes the pool.

The threads for the pool are created here, but not started yet.

See also:
start

void VCF::ThreadPool::postWork Runnable workToDo  )  [inline]
 

This method adds the new work item to the queue of work items and returns immediately.

It temporarily locks the workMtx to protect access to the queue, thus it's a thread safe method to call. After the item is added, one thread from the pool is notified of this, so that it can get the next item on the queue and run it. It's very important to note that you must always pass items in on the heap, i.e. you cannot pass a pointer to an item that has been allocated on the stack. For exameple:

    \\correct way
    Runnable* workItem = new MyRunnable();
    pool.postWork( workItem );

    \\INCORRECT way
    Runnable workItem;
    pool.postWork( &workItem );
The reason this is important is that the pool will manage the lifetime of the Runnable instance and will delete it for you. Passing a pointer to an item allocated on the stack will lead to memory corruption.

Parameters:
Runnable a new isntance of work to perform in form of a Runnable instance. The instance's run method will eventually be called when the work is ready to be executed.

void VCF::ThreadPool::start  )  [inline]
 

Starts the pool's threads running.

The threads that were created by the call to initPool() are now started here. Once all the threads are running, the method exits.

void VCF::ThreadPool::stop  )  [inline]
 

Stop the pool from running.

This will stop and shutdown all the pool's threads, and delete any remaing work items. This call will block until all of the above has been accomplished.

void VCF::ThreadPool::wait uint32  timeoutInMilliseconds  )  [inline]
 

Waits for all work to be finished.

Note that while all the work on the current pool may be "done", the pool can still be "running", waiting for new work to do. This will block for the specified number of miiliseconds, until there is no more work in the queue left, or until the ThreadPool::stop() method is called.

Parameters:
uint32 the number of milliseconds to wait before returning from a timeout. Note that the function may return sooner than the specified number of millseconds if all the work is finished by then.

void VCF::ThreadPool::wait  )  [inline]
 

Waits for all work to be finished.

Note that while all the work on the current pool may be "done", the pool can still be "running", waiting for new work to do. This will block indefinitely, until there is no more work in the queue left, or until the ThreadPool::stop() method is called.

Runnable* VCF::ThreadPool::waitForWork  )  [inline]
 

Call this method to wait until new work has arrived.

This method will block until there is a work item that can be returned. If there is existing work on the queue then it will return immediately.

This method is called by the PoolThread in a loop.
Note that the caller is responsible for deleting the Runnable instance returned by this method.
Returns:
Runnable indicates a new wortk item that can be run. This may be NULL if there is no work to be done because the ThreadPool instance is being shut down as a result of the ThreadPool::stop() method being called.
See also:
ThreadPool::stop()

Runnable

PoolThread

lock down our mutex. check if anything is available, if it is, then get that item, and pop it off the queue and return If nothing is left (i.e. the queue is empty), then notify *all* the threads waiting. Check the result at this point, if it's NOT NULL, then return, otherwise...

Wait for some work item to arrive!

Ha! Work has arrived! Lock down our mutex again. Check for work, if we have any get the work item ,and pop it off the queue. If the queue is empty at this point after getting the work item, broadcast this to everyone waiting on the thread pool (by calling ThreadPool::wait()).


Member Data Documentation

Mutex VCF::ThreadPool::cdtnMtx_
 

bool VCF::ThreadPool::stopped_
 

The variable used to tell if the pool is being shut down as a result of the ThreadPool::stop() method being called.

The default value is "false", and calling stop() sets it to "true".

std::vector<PoolThread*> VCF::ThreadPool::threads_
 

A vector of threads that are being run by the pool.

Each thread instance is based on the PoolThread class.

Condition VCF::ThreadPool::waitForWorkDone_
 

The condition used to indicate that all the work has been completed/processed.

Mutex VCF::ThreadPool::waitForWorkDoneMtx_
 

std::deque<Runnable*> VCF::ThreadPool::work_
 

A queue of work to be performed.

Each item needs to implement the Runnable interface. Any remaining items are destroyed by the pool.

Condition VCF::ThreadPool::workAvailable_
 

The condition used to indicate whether or not there is work available.

Mutex VCF::ThreadPool::workMtx_
 

The mutext to protect access to the work_, and stopped_ variables.


The documentation for this class was generated from the following file:
   Comments or Suggestions?    License Information