c++线程池

来源:互联网 发布:java 多继承 编辑:程序博客网 时间:2024/05/29 19:39

#ifndef THREADPOOL_H
#define THREADPOOL_H
#include<Windows.h>
#include<queue>
#include<vector>

typedef void (*PTaskFun)(LPVOID lpParam);

struct TASK
{
 PTaskFun pFun;
 LPVOID lpParam;
};

class CThreadPool
{
public:
 CThreadPool();
 ~CThreadPool();

 void Init(int nSize = 4);//初始化线程池
 void Call(PTaskFun pFun, LPVOID lpParam);//把函数添加到线程池
 void EndWait(int nTimeOut = INFINITE);

private:
 static  DWORD WINAPI Run(LPVOID lpParam);//线程池执行函数

 HANDLE m_hStop;
 HANDLE m_hSemaphore;
 HANDLE m_hComplete;

 int m_nRuningCount;
 bool m_bInit;
 int m_nTimeOut;
 
 std::queue<TASK*> m_queTask;//任务队列
 CRITICAL_SECTION m_queTaskCS;
 
 std::vector<HANDLE>m_VecHandle;

};
#endif

 

#include "stdafx.h"
#include "ThreadsPool.h"

#define SAFECLOSEHANDLE(x) if(NULL!=x){CloseHandle(x);x =NULL;}

CThreadPool::CThreadPool():m_bInit(false),m_hStop(NULL),m_nRuningCount(0)
{

}

CThreadPool::~CThreadPool()
{
 DeleteCriticalSection(&m_queTaskCS);
 
 SAFECLOSEHANDLE(m_hStop);
 SAFECLOSEHANDLE(m_hSemaphore);
 SAFECLOSEHANDLE(m_hComplete);

 for(int i = 0; i < m_VecHandle.size(); i++)
 {
  SAFECLOSEHANDLE(m_VecHandle.at(i));
 }
}

void CThreadPool::Init(int nSize /* = 4 */)
{
 if(m_bInit)
 {
  return;
 }

 m_bInit = true;
 InitializeCriticalSection(&m_queTaskCS);
 m_hStop = CreateEvent(NULL, FALSE, FALSE, NULL);
 m_hComplete = CreateEvent(NULL, FALSE, FALSE, NULL);
 m_hSemaphore = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
 
 ResetEvent(m_hStop);
 ResetEvent(m_hComplete);

 m_VecHandle.reserve(nSize);

 for(int i = 0; i < nSize; i++)
 {
  HANDLE h =::CreateThread(NULL, 0, Run, this, 0, NULL);
  m_VecHandle.push_back(h);
 }
}

DWORD WINAPI CThreadPool::Run(LPVOID lpParam)
{
 CThreadPool *This = static_cast<CThreadPool*>(lpParam);
 HANDLE hArr[2] ={This->m_hStop,This->m_hSemaphore};
 
 while(true)
 {
   DWORD dwRes = WaitForMultipleObjects(2, hArr, FALSE, 10);
   int nIndex = dwRes - WAIT_OBJECT_0;

   if(nIndex == 0)//exit
   {
   break;
   }

   if(nIndex == 1)//run task
   {
   //get task from queue
    TASK *pTask = NULL;
   
    EnterCriticalSection(&This->m_queTaskCS);
    if(!This->m_queTask.empty())
    {
     pTask = This->m_queTask.front();
     This->m_queTask.pop();
     This->m_nRuningCount++;
     pTask->pFun(pTask->lpParam);

     This->m_nRuningCount--;
     delete pTask;
     pTask = NULL;

     if(This->m_nRuningCount == 0)
     {
      SetEvent(This->m_hComplete);
     }
    }
   
    LeaveCriticalSection(&This->m_queTaskCS);
   }
 }

 return 0;
}

void CThreadPool::EndWait(int nTimeOut /* = INFINITE */)
{
 m_nTimeOut = nTimeOut;
 SetEvent(m_hStop);

 WaitForSingleObject(m_hComplete, m_nTimeOut);//等待线程执行完
}

void CThreadPool::Call(PTaskFun pFun, LPVOID lpParam)
{
 if(!m_bInit)
 {
  Init();
 }

 TASK * pTask = new TASK;
 
 if(NULL == pTask)
 {
  return;
 }

 TASK task;
 pTask->pFun = pFun;
 pTask->lpParam = lpParam;

 EnterCriticalSection(&m_queTaskCS);
 m_queTask.push(pTask);
 LeaveCriticalSection(&m_queTaskCS);
 ReleaseSemaphore(m_hSemaphore, 1, NULL);
 
}

测试代码:

void TestPool()
{
 CThreadPool pool;

pool.Init(8);//初始化线程池跑8线程
 pool.Call(&print,NULL);
 pool.Call(&print2,"param");

 Sleep(1000);
 pool.EndWait();
}