#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;
}
03-26
235
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
07-27