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

A thread pool implementation

Rate me:
Please Sign up or sign in to vote.
2.33/5 (6 votes)
25 Apr 20032 min read 92.6K   2.7K   21   10
A simple thread pool

Introduction

This article is about a re-usable class for thread pooling. It controls the number of threads used to a prescribed level and schedules the requests to jobs to any of the thread in the pool.

Background

While I was writing an application which has many number of threads, I found it difficult to manage a lot of threads. I thought I should limit the number of threads to a certain level and queue the jobs to the threads. So I decided to implement this re-usable thread pooling class.

Using the code

  1. Insert ThreadPool.cpp & ThreadPool.h in project.
  2. Project Settings
    • On the Project menu, Click Settings.
    • In the Project Settings dialog box, click the C/C++ tab.
    • Select Code Generation from the Category drop-down list box.
    • From the Use Run-Time Library drop-down box, select MULTITHREADED.
    • Click OK.
  3. Call Initialize() with required thread count; Default value is 1. Maximum number of threads and tasks can be recommended. The tasks list size will grow if required. Default values are 24 threads and 1024 task information.
  4. Whenever a job is to be assigned, call AssignTask() with a _cdecl function pointer of the client.
  5. Function will be executed from any of the free thread in thread pool.
  6. If DATA members need to be sync, in the submitted function in client, that has to be done by the client.
  7. When thread count need to be increased/decreased, just call Initialize again. NO Resource/Memory LEAK. The current threads finishes execution; then it will be aborted.
  8. To destroy the thread pool, without deleting threadpool object, call UnInitialize(). This will delete all resources. If threads are still working, after WM_QUIT posting and a small waiting, it terminates all threads.
  9. UnInitialize() is also called from destructor.

In the demo application, use the "work" menu to assign sample jobs to thread pool.

/* S A M P L E - C O D E*/
CMyTestView::CMyTestView()
{
    m_Pool.Initialize(10,  /* Required number of threads */ 
                    20,  /* Max threads expected; Default = 24*/ 
                    2000 /* Max tasks expected at a time; Default=1024 */); 
    // Now only 10 thread will be in the pool; 
    // Second param 20 is just for internal memory allocation.
}

void CMyTestView::OnFirstJob() 
{
    THREAD_POOL_TASK taskInfo = {TEST_DO_TASK1, DoFirstJob, LPVOID(this)};
    m_Pool.AssignTask(&taskInfo );
}

// task submitter second
void CMyTestView::OnSecondJob() 
{
    THREAD_POOL_TASK taskInfo = {TEST_DO_TASK2, DoSecondJob, LPVOID(this)};
    m_Pool.AssignTask(&taskInfo );
}

// Thread pool call back. - for first task
bool DoFirstJob(UINT taskId, LPVOID pData)
{
    CMyTestView *pView = (CMyTestView*)pData;
    return pView->DoJob(taskId);
}

// Thread pool call back. - for second task
bool DoSecondJob(UINT taskId, LPVOID pData)
{
    CMyTestView *pView = (CMyTestView*)pData;
    return pView->DoJob(taskId);
}

// Actual execution goes here.
bool CMyTestView::DoJob(UINT taskId)
{
    switch(taskId)
    {
        case TEST_DO_TASK1:
        {
            m_Message = _T("Doing FIRST job");
            Invalidate(0);
            int nCount = 1;
            while (nCount--)
            {
                Sleep(1000);    
                Beep(100, 1000);
            }
        }
        break;
        case TEST_DO_TASK2:
        {
            m_Message = _T("Doing SECOND job");
            Invalidate(0);
            int nCount = 2;
            while (nCount--)
            {
                Sleep(2000);    
                Beep(200, 2000);
            }
        }
    }
    return true;
}

void CMyTestView::OnResetWorkLoad() 
{
    m_Message = _T("On Reset Work Load");
    Invalidate(0);
    m_Pool.Initialize(5,   /* Required number of threads */  
            20,  /* Max threads expected; Default = 24*/ 
            2000 /* Max tasks expected at a time; Default=1024 */);    
    // Now only 5 thread will be in the pool; 
    // Out of previous TEN, FIVE will be removed.
}

Points of Interest

I learned the usefulness of thread pooling. The annoying thing is that global functions are needed for callback functions. I managed it with the help of static functions within the classes.

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
Japan Japan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generaltwo errors after I read it Pin
hephaestus_lee22-May-07 23:16
hephaestus_lee22-May-07 23:16 
Thank the author provide the source.
I found two errors.

1.need set a event after setup message queue.
PostThreadMsg must be called after waitfor this event

2.TerminalThread is a critical error,never use it.
the thread should end by itself.

this line is error:
while (WM_QUIT != GetMessage(&msg, NULL, 0, 0) )
so it never ends.
After fix it,you can waitforxxx (hThread,INFINITE) to wait all threads end normally.

It runs perfectly after fixed them.



QuestionRe: two errors after I read it Pin
charian092028-Jun-07 22:06
charian092028-Jun-07 22:06 
GeneralRe: two errors after I read it Pin
MrZhangjianliang20-Jul-07 0:52
MrZhangjianliang20-Jul-07 0:52 
GeneralQuestions Pin
Name_fa16-Feb-07 14:00
Name_fa16-Feb-07 14:00 
GeneralRe: Questions Pin
Rajgkk20-Feb-07 0:16
Rajgkk20-Feb-07 0:16 
GeneralRe: Questions Pin
Name_fa20-Feb-07 7:16
Name_fa20-Feb-07 7:16 
GeneralSo make a static entry in your class Pin
Frank Driesens1-May-03 0:43
Frank Driesens1-May-03 0:43 
GeneralCThreadPool - ATL7 Pin
TW27-Apr-03 1:45
TW27-Apr-03 1:45 
GeneralRe: CThreadPool - ATL7 Pin
Anonymous30-Apr-03 7:07
Anonymous30-Apr-03 7:07 
GeneralRe: CThreadPool - ATL7 Pin
Rajgkk20-Feb-07 0:14
Rajgkk20-Feb-07 0:14 

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.