方便以后使用,把之前实现的线程池代码贴出来
可能会有一些问题,请自己根据使用情况调整。
头文件 ThreadPoolManage.h
#pragma once
#include <string>
#include <vector>
#include <algorithm>
#include <Windows.h>
using namespace std;
#define MAXTHREADNUM 2
typedef enum _ThreadState
{
THREAD_IDLE = 0,
THREAD_RUNNING = 1
}ThreadState;
class CLockObject
{
public:
virtual BOOL Lock() = 0;
virtual BOOL UnLock() = 0;
};
class CThreadMutex : public CLockObject
{
public:
CThreadMutex();
~CThreadMutex();
BOOL Lock();
BOOL UnLock();
private:
CRITICAL_SECTION m_CritSec;
};
class CThreadCondition
{
private:
HANDLE m_hEvent;
public:
CThreadCondition();
~CThreadCondition();
void Wait();
void Signal();
};
class CThread
{
public:
CThread();
virtual ~CThread();
virtual void Run() = 0;
private:
int m_nErrCode;
unsigned long m_ThreadID;
ThreadState m_ThreadState;
HANDLE m_hThreadHandle;
protected:
static unsigned int __stdcall ThreadFunction(void*);
public:
bool Start();
bool Terminate();
void SetThreadState(ThreadState state);
ThreadState GetThreadState();
void SetErrCode(int nErrCode);
int GetErrCode();
int GetThreadID();
void SetThreadHandle(HANDLE hThread);
HANDLE GetThreadHandle();
};
class CThreadPool;
class CJob;
class CWorkThread : public CThread
{
public:
CWorkThread();
virtual ~CWorkThread();
private:
CThreadPool *m_ThreadPool;
CJob *m_Job;
void *m_JobData;
CThreadMutex m_VarMutex;
public:
CThreadCondition m_JobCond;
CThreadMutex m_WorkMutex;
void Run();
void SetJob(CJob *pJob, void *pJobData);
CJob *GetJob();
void SetThreadPool(CThreadPool *pThreadPool);
CThreadPool *GetThreadPool();
};
class CJob
{
public:
CJob();
virtual ~CJob();
CThread *GetWorkThread();
bool SetWorkThread(CThread *pWorkThread);
virtual void Run(void *ptr) = 0;
private:
CThread *m_pWorkThread;
};
class CWorkJob : public CJob
{
public:
CWorkJob();
~CWorkJob();
void Run(void *pJobData);
};
class CThreadPool
{
public:
CThreadPool();
CThreadPool(int nInitNum);
virtual ~CThreadPool();
private:
int m_MaxNum;
int m_AvailNum;
public:
CWorkThread *GetIdleThread();
void MoveToBusyList(CWorkThread *pWorkThread);
void MoveToIdleList(CWorkThread *pIdleThread);
void AppendToIdleList(CWorkThread *pJobThread);
CThreadMutex m_BusyMutex;
CThreadMutex m_IdleMutex;
CThreadMutex m_JobMutex;
CThreadMutex m_VarMutex;
CThreadCondition m_BusyCond;
CThreadCondition m_IdleCond;
CThreadCondition m_IdleJobCond;
CThreadCondition m_MaxNumCond;
vector<CWorkThread*> m_ThreadList;
vector<CWorkThread*> m_BusyList;
vector<CWorkThread*> m_IdleList;
int GetAvailNum();
int GetAllThreadNum();
int GetBusyNum();
void TerminateAll();
void Run(CJob *pJob, void *pJobData);
};
class CThreadManage
{
public:
CThreadManage();
CThreadManage(int nNumOfThread);
virtual ~CThreadManage();
private:
CThreadPool *m_pPool;
int m_nNumOfThread;
public:
void Run(CJob *pJob, void *pJobData);
void TerminateAll();
};
cpp文件 ThreadPoolManage.cpp
#include "StdAfx.h"
#include "ThreadPoolManage.h"
//CThreadMutex
CThreadMutex::CThreadMutex()
{
#if (_WIN32_WINNT >= 0x0403)
::InitializeCriticalSectionAndSpinCount(&m_CritSec, 4000);
#else
::InitializeCriticalSection(&m_CritSec);
#endif
}
CThreadMutex::~CThreadMutex()
{
::DeleteCriticalSection(&m_CritSec);
}
BOOL CThreadMutex::Lock()
{
::EnterCriticalSection(&m_CritSec);
return TRUE;
}
BOOL CThreadMutex::UnLock()
{
::LeaveCriticalSection(&m_CritSec);
return TRUE;
}
//CThreadCondition
CThreadCondition::CThreadCondition()
{
m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
}
CThreadCondition::~CThreadCondition()
{
if (NULL != m_hEvent)
{
::CloseHandle((m_hEvent));
}
}
void CThreadCondition::Wait()
{
//If dwMilliseconds is INFINITE, the function will return only when the object is signaled.
WaitForSingleObject(m_hEvent, INFINITE);
ResetEvent(m_hEvent);
}
void CThreadCondition::Signal()
{
//Sets the specified event object to the signaled state
SetEvent(m_hEvent);
}
//CThread
CThread::CThread()
{
}
CThread::~CThread()
{
}
unsigned int __stdcall CThread::ThreadFunction(void *pArg)
{
CThread *pThread = (CThread*)pArg;
pThread->Run();
return 0;
}
bool CThread::Start(void)
{
unsigned int threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunction, this, 0, &threadID);
this->m_ThreadID = threadID;
this->SetThreadHandle(hThread);
return true;
}
bool CThread::Terminate(void)
{
_endthreadex(0);
return true;
}
void CThread::SetThreadState(ThreadState state)
{
m_ThreadState = state;
}
ThreadState CThread::GetThreadState()
{
return m_ThreadState;
}
void CThread::SetThreadHandle(HANDLE hThread)
{
m_hThreadHandle = hThread;
}
HANDLE CThread::GetThreadHandle()
{
return m_hThreadHandle;
}
int CThread::GetThreadID()
{
return m_ThreadID;
}
void CThread::SetErrCode(int nErrCode)
{
m_nErrCode = nErrCode;
}
int CThread::GetErrCode()
{
return m_nErrCode;
}
//CWorkThread
CWorkThread::CWorkThread()
{
m_Job = NULL;
m_JobData = NULL;
m_ThreadPool = NULL;
}
CWorkThread::~CWorkThread()
{
if (NULL != m_Job)
{
delete m_Job;
m_Job = NULL;
}
if (m_ThreadPool != NULL)
{
delete m_ThreadPool;
m_ThreadPool = NULL;
}
}
void CWorkThread::Run()
{
for (;;)
{
while (m_Job == NULL)
{
m_JobCond.Wait();
}
m_Job->Run(m_JobData);
m_Job->SetWorkThread(NULL);
//delete m_Job;
m_Job = NULL;
m_ThreadPool->MoveToIdleList(this);
m_WorkMutex.UnLock();
}
}
void CWorkThread::SetJob(CJob *pJob, void *pJobData)
{
m_VarMutex.Lock();
m_Job = pJob;
m_JobData = pJobData;
pJob->SetWorkThread(this);
m_VarMutex.UnLock();
m_JobCond.Signal();
}
CJob* CWorkThread::GetJob()
{
return m_Job;
}
void CWorkThread::SetThreadPool(CThreadPool *pThreadPool)
{
m_VarMutex.Lock();
m_ThreadPool = pThreadPool;
m_VarMutex.UnLock();
}
CThreadPool* CWorkThread::GetThreadPool()
{
return m_ThreadPool;
}
//CJob
CJob::CJob()
{
}
CJob::~CJob()
{
}
CThread* CJob::GetWorkThread()
{
return m_pWorkThread;
}
bool CJob::SetWorkThread(CThread *pWorkThread)
{
m_pWorkThread = pWorkThread;
return true;
}
//CWorkJob
CWorkJob::CWorkJob()
{
}
CWorkJob::~CWorkJob()
{
}
void CWorkJob::Run(void *pJobData)
{
}
//CThreadPool
CThreadPool::CThreadPool(void)
{
m_MaxNum = MAXTHREADNUM;
m_AvailNum = MAXTHREADNUM;
m_BusyList.clear();
m_IdleList.clear();
for (int i = 0; i < m_MaxNum; i++)
{
CWorkThread *pThread = new CWorkThread();
pThread->SetThreadPool(this);
AppendToIdleList(pThread);
pThread->Start();
}
}
CThreadPool::~CThreadPool(void)
{
TerminateAll();
}
CThreadPool::CThreadPool(int nInitNum)
{
m_MaxNum = nInitNum;
m_AvailNum = nInitNum;
m_BusyList.clear();
m_IdleList.clear();
for (int i = 0; i < m_MaxNum; i++)
{
CWorkThread *pThread = new CWorkThread();
pThread->SetThreadPool(this);
AppendToIdleList(pThread);
pThread->Start();
}
}
CWorkThread* CThreadPool::GetIdleThread()
{
while (m_IdleList.size() == 0)
{
m_IdleCond.Wait();
}
m_IdleMutex.Lock();
if (m_IdleList.size() > 0 )
{
CWorkThread *pThread = (CWorkThread*)m_IdleList.front();
m_IdleMutex.UnLock();
return pThread;
}
m_IdleMutex.UnLock();
return NULL;
}
void CThreadPool::MoveToBusyList(CWorkThread *pWorkThread)
{
m_BusyMutex.Lock();
m_BusyList.push_back(pWorkThread);
m_AvailNum--;
m_BusyMutex.UnLock();
m_IdleMutex.Lock();
vector<CWorkThread*>::iterator pos;
pos = find(m_IdleList.begin(), m_IdleList.end(), pWorkThread);
if (pos != m_IdleList.end())
{
m_IdleList.erase(pos);
}
m_IdleMutex.UnLock();
}
void CThreadPool::MoveToIdleList(CWorkThread *pIdleThread)
{
m_IdleMutex.Lock();
m_IdleList.push_back(pIdleThread);
m_AvailNum++;
m_IdleMutex.UnLock();
m_BusyMutex.Lock();
vector<CWorkThread*>::iterator pos;
pos = find(m_BusyList.begin(), m_BusyList.end(), pIdleThread);
if (pos != m_BusyList.end())
{
m_BusyList.erase(pos);
}
m_BusyMutex.UnLock();
m_IdleCond.Signal();
m_MaxNumCond.Signal();
}
void CThreadPool::AppendToIdleList(CWorkThread *pJobThread)
{
m_IdleMutex.Lock();
m_IdleList.push_back(pJobThread);
m_ThreadList.push_back(pJobThread);
m_IdleMutex.UnLock();
}
void CThreadPool::TerminateAll()
{
for (int i = 0; i < m_ThreadList.size(); i++)
{
CWorkThread *pThread = m_ThreadList[i];
pThread->Terminate();
}
return;
}
void CThreadPool::Run(CJob *pJob, void *pJobData)
{
if (GetBusyNum() == m_MaxNum)
{
m_MaxNumCond.Wait();
}
CWorkThread *pIdleThread = GetIdleThread();
if (pIdleThread != NULL)
{
pIdleThread->m_WorkMutex.Lock();
MoveToBusyList(pIdleThread);
pIdleThread->SetThreadPool(this);
pJob->SetWorkThread(pIdleThread);
pIdleThread->SetJob(pJob, pJobData);
}
}
int CThreadPool::GetAvailNum()
{
return m_IdleList.size();
}
int CThreadPool::GetBusyNum()
{
return m_BusyList.size();
}
int CThreadPool::GetAllThreadNum()
{
return m_ThreadList.size();
}
//CThreadManage
CThreadManage::CThreadManage()
{
m_pPool = new CThreadPool();
}
CThreadManage::CThreadManage(int nNumOfThread)
{
m_nNumOfThread = nNumOfThread;
m_pPool = new CThreadPool(nNumOfThread);
}
CThreadManage::~CThreadManage()
{
if (NULL != m_pPool)
{
TerminateAll();
delete m_pPool;
m_pPool = NULL;
}
}
void CThreadManage::Run(CJob *pJob, void *pJobData)
{
m_pPool->Run(pJob, pJobData);
}
void CThreadManage::TerminateAll()
{
m_pPool->TerminateAll();
}