Click here to Skip to main content
Click here to Skip to main content

A thread pool implementation

, 25 Apr 2003
Rate this:
Please Sign up or sign in to vote.
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

Share

About the Author

No Biography provided

Comments and Discussions

 
Generaltwo errors after I read it Pinmemberhephaestus_lee23-May-07 0:16 
QuestionRe: two errors after I read it Pinmembercharian092028-Jun-07 23:06 
GeneralRe: two errors after I read it PinmemberMrZhangjianliang20-Jul-07 1:52 
GeneralQuestions PinmemberName_fa16-Feb-07 15:00 
GeneralRe: Questions PinmemberRajgkk20-Feb-07 1:16 
GeneralRe: Questions PinmemberName_fa20-Feb-07 8:16 
GeneralSo make a static entry in your class PinmemberFrank Driesens1-May-03 1:43 
GeneralCThreadPool - ATL7 PinmemberTW27-Apr-03 2:45 
GeneralRe: CThreadPool - ATL7 PinsussAnonymous30-Apr-03 8:07 
GeneralRe: CThreadPool - ATL7 PinmemberRajgkk20-Feb-07 1:14 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.1411023.1 | Last Updated 26 Apr 2003
Article Copyright 2003 by Rajeev Sadasivan
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid