Click here to Skip to main content
15,908,166 members
Articles / Programming Languages / C++
Article

An easy to use worker thread

Rate me:
Please Sign up or sign in to vote.
4.92/5 (6 votes)
30 Oct 20011 min read 101.6K   1.1K   20   17
Use worker threads in your application without the complicated details

Sample Image - WorkerThread.gif

Introduction

I had the need for a worker thread which is easy to use and is independent of libraries like MFC. So I wrote a class called CWorkerThread which fits my needs. It provides functionality to execute an unlimited amount of functions in a single thread. The functions are processed syncronously in the order the events which are related to these functions are fired.

How it works

The CWorkerThread class has a method called AddEvent(HANDLE hEvent, EVENTPROC pProc, LPVOID pProcParam = NULL); This function takes a handle, a static or global function and an optional void pointer. The function pProc is executed when the event hEvent occurs. The pProcParam parameter is passed to that function. You can call AddEvent(...) for all events you want the thread to process. To start the thread call the objects Start(const int& nPriority = THREAD_PRIORITY_NORMAL); method. This will create the thread and initialize it's event queue. When you now set an event, the related function will be executed. To give you an impression of this event queue I pasted the code of the threads "main" thread procedure here:

UINT CWorkerThread::ThreadProc(LPVOID pProcParam)
{
    assert(pProcParam);

    CWorkerThread* pThread = reinterpret_cast<CWorkerThread*>(pProcParam);
    DWORD dwResult = 0;

    int nSize = pThread->m_arrEvents.size();
    HANDLE* pArrEvents = new HANDLE[nSize];
    for (int i = 0; i < nSize; i++)
        pArrEvents[i] = pThread->m_arrEvents[i].hEvent;

    // Install the event queue...
    while (true)
    {
        dwResult = ::WaitForMultipleObjects(nSize,
                                            pArrEvents,
                                            FALSE,
                                            INFINITE) - WAIT_OBJECT_0;

        if (dwResult == WORKERTHREADEVENT_KILL)
            break;
		
        // Execute appropriate function...
        (pThread->m_arrEvents[dwResult].pProc)(
             pThread->m_arrEvents[dwResult].pProcParam);
    }

    delete[] pArrEvents;
	
    ::SetEvent(pThread->m_hEventIsKilled);
    return 0;
}

Conclusion

The supplied sample application will show you how it works. If you need help with this or have suggestions on how to improve it or state bugs, feel free to drop me an email. Updated versions may be found at http://www.nitrobit.com/ or http://www.codecommunity.com/.

License

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMaybe Demo....(not only one WorkerThread) Pin
player.20-Sep-06 2:49
player.20-Sep-06 2:49 
GeneralGreat work, got my 5 points! Pin
Lars [Large] Werner25-Aug-06 8:46
professionalLars [Large] Werner25-Aug-06 8:46 
GeneralNice Pin
tyb26-Aug-05 16:11
tyb26-Aug-05 16:11 
Generaladding and removing events Pin
fioresoft18-Feb-04 16:24
fioresoft18-Feb-04 16:24 
GeneralRemoving events from queue Pin
11-Feb-02 0:29
suss11-Feb-02 0:29 
QuestionNot starting again ? Pin
Yves21-Nov-01 19:04
Yves21-Nov-01 19:04 
Answerstarts perfectly... Pin
9-Feb-02 2:50
suss9-Feb-02 2:50 
GeneralRe: starts perfectly... Pin
Bhikshapathi Gorantla1-Apr-02 21:56
Bhikshapathi Gorantla1-Apr-02 21:56 
GeneralRe: starts perfectly... Pin
15-Apr-02 6:15
suss15-Apr-02 6:15 
GeneralMinor correction Pin
19-Nov-01 8:56
suss19-Nov-01 8:56 
GeneralQuestion Pin
Todd Smith31-Oct-01 12:57
Todd Smith31-Oct-01 12:57 
GeneralRe: Question Pin
1-Nov-01 0:25
suss1-Nov-01 0:25 
GeneralSome improvement ideas Pin
Keith Bussell31-Oct-01 12:40
Keith Bussell31-Oct-01 12:40 
Hi Frank,

This is a good start, but isn't very robust. A few quick things to think about:

1) The main thread proc only checks the size of the event vector once. What happens if new actions get added after the thread starts?

2) Because the event vector will be accessed from more than one thread, you should protect it with a critical section.

3) Is the intent of this worker thread to a) run queued actions once, or to b) have the actions get spawned multiple times (i.e. triggering the same action to occur multiple times by setting the associated event multiple times)?
If a, you have no way of removing items from the queue.
If b, you have no way of ensuring actions get processed. (Imagine the worker thread is processing some action, and then the main thread wants another action to run several times. It'll call SetEvent on some event multiple times. The action associated with that event will only get called once.) There are other timing issues that can occur because you're using events.
One option would be to have the worker thread run the action as soon as it gets queued.

4) There's no way to remove actions from the queue. One suggestion to fix this is to have AddEvent return an event id. Then you could add a RemoveEvent function to get rid of it.

5) General error checking (e.g. return value from WaitForMultipleObjects, watch out for calling Start() multiple times, etc.)

Ok, that's all for now. Have a good one.
GeneralRe: Some improvement ideas Pin
Todd Smith31-Oct-01 13:34
Todd Smith31-Oct-01 13:34 
GeneralRe: Some improvement ideas Pin
Keith Bussell1-Nov-01 6:43
Keith Bussell1-Nov-01 6:43 
GeneralRe: Some improvement ideas Pin
1-Nov-01 0:41
suss1-Nov-01 0:41 
GeneralRe: Some improvement ideas Pin
Keith Bussell1-Nov-01 8:56
Keith Bussell1-Nov-01 8:56 

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.