C++ 线程池源代码实现3

来源:互联网 发布:矩阵计算 编辑:程序博客网 时间:2024/06/07 09:44

最近在做一个项目,因为需要到多线程,网络上面找了一些代码,现在贴上来,以留备用。

ThreadPool.h头文件

 

#ifndef OTA_THREADPOOL_H_CAESAR__DEF
#define OTA_THREADPOOL_H_CAESAR__DEF

#include <windows.h>

class CWorkDesc
{
public:
 CWorkDesc(){}

 virtual ~CWorkDesc(){}
};

class CWork
{
public:
 CWork(){}
 virtual ~CWork(){}
 virtual void ProcessJob(CWorkDesc* pJob)=0;
};


class CThreadPool
{
 friend static unsigned __stdcall ManagerProc(void* pThread);
 friend static unsigned __stdcall WorkerProc(void* pThread);

 typedef struct  THREADINFO
 {
  THREADINFO()
  {
   hThreadHandle = NULL;
   dwThreadID  = 0;
   bIsBusy   = false;
   bIsQuit   = false;
  }
  HANDLE  hThreadHandle;
  unsigned dwThreadID;
  volatile bool  bIsBusy;
  volatile bool  bIsQuit;
 }*LPTHREADINFO;
 
public:
 CThreadPool();
 virtual ~CThreadPool();
 

 enum EReturnValue
 {
  MANAGERPROC_RETURN_VALUE = 10001,
  WORKERPROC_RETURN_VALUE  = 10002
 };

 enum EThreadStatus
 {
  BUSY,
  NORMAL,
  IDLE
 };

 bool Start(WORD wStatic,WORD wMax);
 void Stop(void);
 void ProcessJob(CWorkDesc* pJob, CWork* pWorker) const;
  
protected:

 static unsigned __stdcall ManagerProc(void* pThread);
 static unsigned __stdcall WorkerProc(void* pThread);
 
 LPTHREADINFO  m_pThreadInfo;

 volatile WORD  m_wStaticThreadNum;
 volatile WORD  m_wMaxThreadNum;
 volatile bool  m_bQuitManager;
 DWORD    m_dwMSeconds;

 HANDLE    m_hManagerIO;
 HANDLE    m_hWorkerIO;

 HANDLE    m_hManagerThread;
 CRITICAL_SECTION m_csLock;
private:
 CThreadPool::EThreadStatus GetWorkThreadStatus();
 void AddThread(void);
 void DelThread(void);
 int  GetThreadbyID(DWORD dwID);
};
#endif

 

 

ThreadPool.cp 实现文件

 

#include "StdAfx.h"
#include "ThreadPool.h"
#include "process.h"

CThreadPool::CThreadPool()
{
 m_hManagerIO = NULL;
 m_hWorkerIO  = NULL;

 m_hManagerThread= NULL;
 m_pThreadInfo = NULL;
 
 m_dwMSeconds = 200;
 m_bQuitManager = false;
 //初使化互斥体
 ::InitializeCriticalSection(&m_csLock);
}

CThreadPool::~CThreadPool()
{
 //关闭IO
 if(m_hManagerIO)
 {
  ::CloseHandle(m_hManagerIO);
 }
 if(m_hWorkerIO)
 {
  ::CloseHandle(m_hWorkerIO);
 }
 if(m_pThreadInfo)
 {
  delete [] m_pThreadInfo;
 }
 //关闭互斥体
 ::DeleteCriticalSection(&m_csLock);
}

bool CThreadPool::Start(WORD wStatic,WORD wMax)
{
 if(!(wStatic && wMax))
  return false;
 
 m_wStaticThreadNum = wStatic;
 m_wMaxThreadNum  = wMax;

 //LOCK
 ::EnterCriticalSection(&m_csLock);
 
 //创建工作线程数据
 if(m_pThreadInfo)
 {
  delete [] m_pThreadInfo;
  m_pThreadInfo = NULL;
 }
 m_pThreadInfo = new THREADINFO[wMax]();
 if(m_pThreadInfo == NULL)
  return false;


 //创建异步的不关联文件的完全IO端口
 if(m_hManagerIO)
 {
  ::CloseHandle(m_hManagerIO);
  m_hManagerIO = NULL;
 }
 m_hManagerIO = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
 if(m_hManagerIO == NULL)
 {
  return false;
 }

 if(m_hWorkerIO)
 {
  ::CloseHandle(m_hWorkerIO);
  m_hManagerIO = NULL;
 }
 m_hWorkerIO  = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
 if(m_hWorkerIO == NULL)
 {
  return false;
 }

 //创建管理线程
 m_bQuitManager = false;

 if(m_hManagerThread)
 {
  ::TerminateThread(m_hManagerThread,0);
  m_hManagerThread = NULL;
 }
 unsigned ManagerThreadID;

 m_hManagerThread = (HANDLE)_beginthreadex(NULL,0,ManagerProc,this,0,&ManagerThreadID);

 if(m_hManagerThread == NULL)
 {
  return false;
 }

 //创建工作线程
 for(WORD i=0;i<wStatic;++i)
 {
  m_pThreadInfo[i].hThreadHandle = (HANDLE)_beginthreadex(NULL,0,WorkerProc,this,0,&m_pThreadInfo[i].dwThreadID);
 }
 
 //UNLOCK
 ::LeaveCriticalSection(&m_csLock);

 return true;
}

 


void CThreadPool::Stop(void)
{
 //LOCK
 ::EnterCriticalSection(&m_csLock);
 
 //向管理线程发送关闭线程消息
 m_bQuitManager = true;

 //判断并关闭管理线程
 DWORD dwRes;
 
 for(int i=0;i<10;i++)
 {
  ::GetExitCodeThread(m_hManagerThread,&dwRes);
  if(dwRes == CThreadPool::MANAGERPROC_RETURN_VALUE)
  {
   break;
  }
  if(i == 9)
  {
   //关闭线程
   ::TerminateThread(m_hManagerThread,0);
  }
  else
  {
   ::Sleep(1000);
  }
 }

 //关闭IO
 ::CloseHandle(m_hManagerIO);
 m_hManagerIO = NULL;

 //关闭所有工作线程
 
 for(int i=0;i<m_wMaxThreadNum;i++)
 {
  if(m_pThreadInfo[i].dwThreadID == 0)
  {
   continue;
  }
  
  m_pThreadInfo[i].bIsQuit = true;
  
  for(int j=0;j<10;j++)
  {
   ::GetExitCodeThread(m_pThreadInfo[i].hThreadHandle,&dwRes);

   if(dwRes == CThreadPool::WORKERPROC_RETURN_VALUE)
   {
    break;
   }
   if(j == 9)
   {
    ::TerminateThread(m_pThreadInfo[i].hThreadHandle,0);
   }
   else
   {
    ::Sleep(500);
   }
  }
 }

 //关闭IO
 ::CloseHandle(m_hWorkerIO);
 m_hWorkerIO = NULL;

 //删除线程结构
 if(m_pThreadInfo)
 {
  delete [] m_pThreadInfo;
  m_pThreadInfo = NULL;
 }
 
 //删除所有待处理数据
 unsigned long      pN1,pN2;
 OVERLAPPED*       pOverLapped;
 
 while(::GetQueuedCompletionStatus(m_hWorkerIO,&pN1,&pN2,&pOverLapped,0))
 {
  CWork*  pWork  = reinterpret_cast<CWork*>(pN1);
  CWorkDesc* pWorkDesc = reinterpret_cast<CWorkDesc*>(pN2);
  
  delete pWorkDesc;
 }
 
 //UNLOCK
 ::LeaveCriticalSection(&m_csLock);
}

 


void CThreadPool::ProcessJob(CWorkDesc* pJob, CWork* pWorker) const
{
 ::PostQueuedCompletionStatus(m_hWorkerIO,
   reinterpret_cast<DWORD>(pWorker),
   reinterpret_cast<DWORD>(pJob),
   NULL);
}

 

 

unsigned __stdcall CThreadPool::ManagerProc(void* pThread)
{
 unsigned long      pN1, pN2;
 OVERLAPPED*       pOverLapped;
 
 CThreadPool* pServer = reinterpret_cast<CThreadPool*>(pThread);
 
 while(!pServer->m_bQuitManager)
 {
  if(::GetQueuedCompletionStatus(pServer->m_hManagerIO,&pN1,&pN2,&pOverLapped,pServer->m_dwMSeconds) == TRUE)
  {
   if(pOverLapped == (OVERLAPPED*)0xFFFFFFFF)
   {
    //收到退出码
    break;
   }
  }
  else
  {
   //超时,判断工作线程状态
   EThreadStatus stat =  pServer->GetWorkThreadStatus();
   if(stat == CThreadPool::BUSY)
   {
    puts("Add thread");
    pServer->AddThread();
   }
   else
   if(stat == CThreadPool::IDLE)
   {
    puts("Del thread");
    pServer->DelThread();
   } 
  }
 };
  
 _endthreadex(CThreadPool::MANAGERPROC_RETURN_VALUE);
 
 return CThreadPool::MANAGERPROC_RETURN_VALUE;
}

 


unsigned __stdcall CThreadPool::WorkerProc(void* pThread)
{
 unsigned long      pN1, pN2;
 OVERLAPPED*       pOverLapped;
 CThreadPool* pServer = reinterpret_cast<CThreadPool*>(pThread);
 
 DWORD threadID = ::GetCurrentThreadId();
 int  nSeq  = pServer->GetThreadbyID(threadID);
 
 if(nSeq<0)
 {
  return 0;
 }

 while(!pServer->m_pThreadInfo[nSeq].bIsQuit)
 {
  if(::GetQueuedCompletionStatus(pServer->m_hWorkerIO,&pN1,&pN2,&pOverLapped,pServer->m_dwMSeconds))
  {   
   CWork*  pWork  = reinterpret_cast<CWork*>(pN1);
   CWorkDesc* pWorkDesc = reinterpret_cast<CWorkDesc*>(pN2);

   printf("do work/n");
   //在工作之前将状态设置为Busy
   pServer->m_pThreadInfo[nSeq].bIsBusy = true;   
   
   //工作处理过程
   pWork->ProcessJob(pWorkDesc);
   delete pWorkDesc;
   
   //在工作后将状态设置为非Busy
   pServer->m_pThreadInfo[nSeq].bIsBusy = false;
   printf("do work over/n");
  }
 }

 printf("worker thread down/n");

 //退出之前将线程ID设置为0
 pServer->m_pThreadInfo[nSeq].dwThreadID = 0;

 _endthreadex(CThreadPool::WORKERPROC_RETURN_VALUE);

 return CThreadPool::WORKERPROC_RETURN_VALUE;
}

 

 

CThreadPool::EThreadStatus CThreadPool::GetWorkThreadStatus()
{
 float fAll=0.0,fRun=0.0;
 for(WORD wi=0;wi<m_wMaxThreadNum;++wi)
 {
  if(m_pThreadInfo[wi].dwThreadID)
  {
   fAll++;
   if(m_pThreadInfo[wi].bIsBusy)
   {
    fRun++;
   }
  }
 }

 if(fAll == 0)
  return CThreadPool::IDLE;

 if(fRun/(1.0*fAll)>0.8)
 {
  return CThreadPool::BUSY;
 }
 if(fRun/(1.0*fAll)<0.2)
 {
  return CThreadPool::IDLE;
 }

 return CThreadPool::NORMAL;
}

 


void CThreadPool::AddThread(void)
{
 for(WORD wi=m_wStaticThreadNum;wi<m_wMaxThreadNum;++wi)
 {
  if(!m_pThreadInfo[wi].dwThreadID)
  {
   m_pThreadInfo[wi].bIsBusy  = false;
   m_pThreadInfo[wi].bIsQuit  = false;
   m_pThreadInfo[wi].hThreadHandle = (HANDLE)_beginthreadex(NULL,0,WorkerProc,this,0,&m_pThreadInfo[wi].dwThreadID);
   
   break;
  }
 }
}

 


void CThreadPool::DelThread(void)
{
 for(WORD wi=m_wMaxThreadNum;wi>m_wStaticThreadNum;--wi)
 {
  if(m_pThreadInfo[wi-1].dwThreadID)
  {
   m_pThreadInfo[wi-1].bIsQuit = true;
   ::Sleep(m_dwMSeconds);
   break;
  }
 } 
}

 

 

int CThreadPool::GetThreadbyID(DWORD dwID)
{
 for(WORD wi=0;wi<m_wMaxThreadNum;wi++)
 {
  if(m_pThreadInfo[wi].dwThreadID == dwID)
  {
   return wi;
  }
 }

 return -1;
}

 

 

 

 

 

 

 

 

 

原创粉丝点击