线程池5-CThreadPoolExe

#include"CThreadPoolExe.h"
CThreadPoolExe::CWorker::CWorker(CThreadPoolExe* pThreadPool, CTask* pFirstTask) :
 m_pThreadPool(pThreadPool), m_pFirstTask(pFirstTask), m_bRun(true)
{
}
CThreadPoolExe::CWorker::~CWorker()
{
}
void CThreadPoolExe::CWorker::Run()
{
	CTask* pTask = nullptr;
 	while (m_bRun)
 	{
 		if (nullptr == m_pFirstTask)//如果是初始化的线程需要在队列中获取数据
  		{
   			pTask = m_pThreadPool->GetTask();
  		}
  		else//后期增加的队列,可以直接处理第一个消息
  		{
   			pTask = m_pFirstTask;
   			m_pFirstTask = nullptr;
  		}
  		if (nullptr == pTask)
  		{
  			EnterCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
  			if (m_pThreadPool->GetThreadPoolSize() > m_pThreadPool->m_nMinThreads)
  			{
  				ThreadPoolItr itr = m_pThreadPool->m_ThreadPool.find(this);
  				if (itr != m_pThreadPool->m_ThreadPool.end())
    				{
     					m_pThreadPool->m_ThreadPool.erase(itr);
     					m_pThreadPool->m_TrashThread.insert(this);//加入到回收线程中,等待下次回收
    				}
    				m_bRun = false;
  			}
  			else
  			{
  				ThreadPoolItr itr = m_pThreadPool->m_TrashThread.begin();
   			 	while (itr != m_pThreadPool->m_TrashThread.end())
   			 	{
   			 		(*itr)->Join();//等待回收
     					(*itr)->Destroy();//删除线程
     					m_pThreadPool->m_TrashThread.erase(itr);//从队列中移除
     					itr = m_pThreadPool->m_TrashThread.begin();
   			 	}
  			}
  			LeaveCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
   			continue;
  		}
  		else
  		{
  			pTask->Run();
   			pTask->Destroy();
  		}
 	}
}
CThreadPoolExe::CThreadPoolExe(void) :m_bRun(false), m_bEnableInsertTask(false)
{
	InitializeCriticalSection(&m_csTasksLock);
	InitializeCriticalSection(&m_csThreadPoolLock);
	m_pTasksSemaphore = CreateSemaphore(NULL, 0, 100, NULL);
 	m_pThreadConnect = NULL;
 	m_nMinThreads = 0;
 	m_nMaxThreads = 0;
 	m_nMaxPendingTasks = 0;
}
CThreadPoolExe::~CThreadPoolExe(void)
{
	Terminate();//关闭管理线程
 	DeleteCriticalSection(&m_csTasksLock);//删除边界锁(工作线程)
 	DeleteCriticalSection(&m_csThreadPoolLock);//删除边界锁(管理线程)
 	CloseHandle(m_pTasksSemaphore);
 	if (NULL != m_pThreadConnect)
 	{  	
 		m_pThreadConnect = NULL;
 	}
}
bool CThreadPoolExe::Init(unsigned int unMinThreads, unsigned int unMaxThreads, unsigned int unMaxPendingTasks)
{
	if (0 == unMinThreads)
 	{
 	 	return false;
 	}
 	if (unMaxThreads < unMinThreads)
 	{
  		return false;
 	}
 	m_nMinThreads = unMinThreads;
 	m_nMaxThreads = unMaxThreads;
 	m_nMaxPendingTasks = unMaxPendingTasks;
 	unsigned int i = m_ThreadPool.size();
 	for (; i < unMinThreads; i++)
 	{
 		CWorker* pWorker = new CWorker(this);
 	 	if (NULL == pWorker)
  		{
   			return false;
  		}
  		EnterCriticalSection(&m_csThreadPoolLock);
 		 m_ThreadPool.insert(pWorker);
  		LeaveCriticalSection(&m_csThreadPoolLock);
  		pWorker->Start();
 	}
 	m_bRun = true;
 	m_bEnableInsertTask = true;
 	return true;
}
bool CThreadPoolExe::Execute(CTask* pCTask, int nPriority)
{
	if (!m_bEnableInsertTask)
 	{
 	 	return false;
 	}
 	if (NULL == pCTask)
 	{
  		return false;
 	}
 	if (GetTaskSize() >= m_nMaxPendingTasks)
 	{
 		if (m_ThreadPool.size() < m_nMaxThreads)
 		{
 			CWorker* pWorker = nullptr;
   			if (TASK_PRIORITY_HIGH == nPriority)
   			{
   			 	pWorker = new CWorker(this, pCTask);
   			}
   			else
   			{
    				InsertTaskQueue(pCTask, nPriority);
    				pWorker = new CWorker(this, NULL);
   			}
   			if (nullptr == pWorker)
   			{
    				return false;
   			}
   			EnterCriticalSection(&m_csThreadPoolLock);
   			m_ThreadPool.insert(pWorker);
   			LeaveCriticalSection(&m_csThreadPoolLock);
   			pWorker->Start();
 		}
 		else
 		{
 			return false;
 		}
 	}
 	else
 	{
 		InsertTaskQueue(pCTask, nPriority);
 	}
 	return true;
}
bool CThreadPoolExe::InsertTaskQueue(CTask* pCTask, int nPriority)
{
	if (nullptr == pCTask)
 	{
  		return false;
 	}
 	if (!m_bEnableInsertTask)
 	{
  		return false;
 	}
 	EnterCriticalSection(&m_csTasksLock);
 	if (TASK_PRIORITY_HIGH == nPriority)
 	{
  		m_TasksHigh.push_back(pCTask);
 	}
 	else if (TASK_PRIORITY_MIDDLE == nPriority)
 	{
  		m_TaskMiddle.push_back(pCTask);
 	}
 	else
 	{
 	 	m_TaskLow.push_back(pCTask);
 	}
 	LeaveCriticalSection(&m_csTasksLock);
 	ReleaseSemaphore(m_pTasksSemaphore, 1, NULL);
 	return true;
}
void CThreadPoolExe::Terminate()
{
	m_bEnableInsertTask = false;
 	while (GetTask() > 0)
 	{
 		 Sleep(1);
 	}
 	m_bRun = false;
	 m_nMinThreads = 0;
	 m_nMaxThreads = 0;
	 m_nMaxPendingTasks = 0;
 	while (m_ThreadPool.size() > 0)
 	{
  		Sleep(1);
 	}
 	EnterCriticalSection(&m_csThreadPoolLock);
 	ThreadPoolItr itr = m_TrashThread.begin();
 	while (itr != m_TrashThread.end())
 	{
  		(*itr)->Join();
  		(*itr)->Destroy();
 		 m_TrashThread.erase(itr);
  		itr = m_TrashThread.begin();
 	}
 	LeaveCriticalSection(&m_csThreadPoolLock);
}
unsigned int CThreadPoolExe::GetThreadPoolSize()
{
	 return m_ThreadPool.size();
}
int CThreadPoolExe::StartConnect()
{
	if (NULL == m_pThreadConnect)
 	{
 	 	return -1;
 	}
 	return 0;
}
CTask* CThreadPoolExe::GetTask()
{
	CTask* pTask = nullptr;
	 WaitForSingleObject(m_pTasksSemaphore, 3000);
	 EnterCriticalSection(&m_csTasksLock);
	 if (!m_TasksHigh.empty())
	 {
		  pTask = m_TasksHigh.front();
		  m_TasksHigh.pop_front();
	 }
	 if (!m_TaskMiddle.empty())
	 {
		  pTask = m_TaskMiddle.front();
		  m_TaskMiddle.pop_front();
	 }
	 if (!m_TaskLow.empty())
	 {
		  pTask = m_TaskLow.front();
		  m_TaskLow.pop_front();
	 }
	 LeaveCriticalSection(&m_csTasksLock);
	 return pTask;
}
unsigned int CThreadPoolExe::GetTaskSize()
{
	unsigned int nTaskSize = 0;
	 EnterCriticalSection(&m_csTasksLock);
	 if (!m_TasksHigh.empty())
	 {
		  nTaskSize += m_TasksHigh.size();
	 }
	 if (!m_TaskMiddle.empty())
	 {
		  nTaskSize += m_TaskMiddle.size();
	 }
	 if (!m_TaskLow.empty())
	 {
		  nTaskSize += m_TaskLow.size();
	 }
	 LeaveCriticalSection(&m_csTasksLock);
	 return nTaskSize;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

2020年冬

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

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

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

打赏作者

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

抵扣说明:

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

余额充值