线程池的简单实现

21 篇文章 0 订阅
16 篇文章 0 订阅

方便以后使用,把之前实现的线程池代码贴出来

可能会有一些问题,请自己根据使用情况调整。

头文件 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();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醉逍遥_祥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值