Click here to Skip to main content
13,006,020 members (48,968 online)
Click here to Skip to main content
Add your own
alternative version


34 bookmarked
Posted 7 Nov 2005

WorkerThread Library

, 7 Nov 2005
Rate this:
Please Sign up or sign in to vote.
An article on a generic WorkerThread library.


As all of you know, threads allow a program to be split into two or more simultaneously running tasks. This article contains the design and implementation of a Worker Thread static library. This Worker Thread static library just does a special work like read a file or log some messages into a log file etc. Programmers can use this worker thread library by just including it, if they want to perform a work in a separate thread in their program. In this Worker Thread library I am using a worker thread manager and many worker threads. The worker thread manager will assign a particular work to a free worker thread or simply manage all worker threads. The number of worker threads under a worker thread manager can be set. Each worker thread will perform a particular work. In this WorkerThread library, there is also a WorkerThread queue. You can add your work item into the queue first. The worker thread manager will take (pop) work items from the queue and assign them to free worker threads. The worker thread will perform the work assigned to it.

Class Diagram

Class Description


The WorkerThreadMgr is a thread class derived from CWinThread. This class will poll the WorkerThreadQueue continuously and pop data from it. This class also creates the worker threads on demand and gives the work item read from the queue to A free thread. It contains a WorkerThreadMap with thread ID as the map key and a pointer to WorkerThread as the map value. The structure of the map is given below:

Map IDMap Value
Thread IDPointer to WorkerThread

The class declaration for WorkerThreadMgr is:

class WorkerThreadMgr : public CWinThread
    // This function will put the WorkItem object into the queue
    bool AddWorkItem( WorkItem* pWorktem_i );

    // Terminates the worker thread
    bool Terminate();

    // Returns the Status of the WorkerThreadMgr thread
    bool IsRunning();


    // Kills the Worker Threads
    bool KillWorkerThreads();


    // Queue Object
    WorkerThreadQueue<WorkItem*,WorkItem*> m_WorkQueue;

    // Map containing Thread Id as Key and WorkerThread as Value
    CMapDWordToWorkerThread m_WorkerThreadMap;

Applications can put the WorkItem object into the WorkerThread queue using the AddWorkItem function.

The InitInstance function is overridden from the CWinThread class. This will be the thread function of this class. This function is called when the constructor method creates the thread using a CreateThread() call. The queue polling for a worker thread will be done here. During the queue polling, this function will iterate the worker thread map to get a free thread. If it does not get a worker thread with a status as free from the map, then it will create a new worker thread and add the worker thread into the map. Also it will set the thread status as running. If it gets a free worker thread from the map, then it will start that particular thread and set its status as running.

The Terminate() function will set the thread status of the WorkerthreadMgr as not running. This function is synchronized using a critical section object.

Since WorkerThreadMgr itself is a thread, we need to know its running status. The IsRunning function will return the thread status (running or not) of the WorkerThreadMgr. This function is synchronized using a critical section object.

The KillWorkerThreads private function will iterate the WorkerThread map and kill all worker threads in the map. This function will call the Terminate() function to terminate the WorkerThread.


This also is a CWinThread derived class and it is created by the worker thread manager. The main functionality of this class is to receive the DO_WORK message from the WorkerThreadMgr. The OnDoWork() function is called when the DO_WORK message is received.

class WorkerThread : public CWinThread

    // Do a specific work
    afx_msg LRESULT OnDoWork( WPARAM wParam_i, LPARAM lParam_i );

    // Exit the worker thread
    afx_msg LRESULT OnExitThread( WPARAM wParam_i, LPARAM lParam_i );

    // Check Thread is idle or not
    bool IsIdle();

    // Terminate the worker thread
    bool Terminate();

The OnDoWork is a message handler function that is called when the WorkerThread receives the DO_WORK message. This function mainly performs the work. So it will call the DoWork() of the WorkItem class.

Similarly, the OnExitThread message handler function is called when receiving the EXIT_WORKERTHREAD message to terminate the WorkerThread.


This class contains the generic implementation of the queue data structure using the CList class of MFC. It uses templates so that it can hold any data type. This class also provides a critical section object to synchronize the Push and Pop operations from different threads. The class declaration is like below:

template<class TYPE, class ARG_TYPE>
class WorkerThreadQueue

We can add (push) and pop work items from the queue. The Pop() function returns an element from the queue. The push and pop operations are synchronized using the critical section object.

// Push the WorkItem into the Queue
void Push( ARG_TYPE Item_i )
    ::EnterCriticalSection( &m_CriticalSection );

    m_Container.AddTail( Item_i );

    ::LeaveCriticalSection( &m_CriticalSection );

// Pop the WorkItem from the Queue
// Returns the WorkItem from the Queue
// (WorkItem of a generic type)
    ::EnterCriticalSection( &m_CriticalSection );

    ARG_TYPE WorkItemData = m_Container.RemoveHead();

    ::LeaveCriticalSection( &m_CriticalSection );
    return WorkItemData;


The WorkItem is a generic class to do a special work. This class has a pure virtual DoWork() function called from the OnDoWork() of WorkerThread. We can create a class of type WorkItem and override the DoWork() function to perform the specific work.

class WorkItem 

    virtual ~WorkItem() {};

    // Do a special work
    virtual void DoWork() = 0;

How to Use It?

After building the WorkerThread source, it will generate a WorkerThread.lib. Programs which want to use this library must include this WorkerThread.lib. The classes that do special work (for example, the FileLogger logs messages into a file) shall be derived from the WorkItem parent class to get the DoWork() method as an overridden function. Also the WorkItem (Message in the case of FileLogger) shall be put into the queue of the WorkerThread using the AddWorkItem() of WorkerThreadMgr.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Web Developer
India India
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralVC++ Worker Threads Problem Pin
Irtiza200022-Mar-06 2:46
memberIrtiza200022-Mar-06 2:46 
GeneralRe: VC++ Worker Threads Problem Pin
bob1697222-Mar-06 3:15
memberbob1697222-Mar-06 3:15 
I'm not sure about using the authors class but in general you'd...

// Define for user registered message to postmessage from thread to thread

// Use the GUID generator to create a statistacally unique name
// This method well documented by Joseph Newcomer at in MVP tips section
const UINT UWM_DO_WORK=::RegisterWindowMessage("UWM_DO_WORK_063B39D9-9E1D-4fb9-A9B2-7B148A5589E6");

// In your main class header above or in the //Generated message map functions section...
afx_msg BOOL OnDoWork(WPARAM wParam, LPARAM lParam);

// In your .cpp file for your main class (i.e. CYourDerivedDialog)

// Wizard created stuff here


// In your main class whereever you spawn the thread
// (I forgot to designate this section in original post) Sorry about that

if (m_pWorkerThread) {
// Place any data into the members of your CWorkerThread class members here

m_pWorkerThread->ResumeThread(); // Start the search

// Your CWorkerThread::InitInstance acts as your controlling function for your thread
// Pass a message to the thread initiator informing of an increment of task completed

BOOL CWorkerThread::InitInstance()
// TODO: perform and per-thread initialization here

while (/*still doing work*/) {
// Call other thread functions until task complete

// Some syncronization technique to allow user to abort gets checked
// Check some Boolean member that the initiator sets when aborting

this->m_pMainWnd->PostMessage(UWM_DO_WORK); // Post message


return FALSE; // Exit thread

BOOL CYourDlg::OnDoWork(WPARAM wParam, LPARAM lParam)
m_nCurrentStatus++; // Increment the processed count

ProcessEvent(); // Update UI with some function

return 0; // Value is ignored

Hope that helps.

-- modified at 10:56 Wednesday 22nd March, 2006
GeneralQuick patch to the memory leak Pin
bohannan21-Feb-06 18:05
memberbohannan21-Feb-06 18:05 
QuestionCan improve Pin
jellow23-Nov-05 20:19
memberjellow23-Nov-05 20:19 
GeneralGood Work NeSTian Pin
renjith_sree23-Nov-05 19:05
memberrenjith_sree23-Nov-05 19:05 
GeneralA few problems. Pin
Peter Ritchie15-Nov-05 8:06
memberPeter Ritchie15-Nov-05 8:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170628.1 | Last Updated 7 Nov 2005
Article Copyright 2005 by Ethihas
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid