📄 arwinthreadpool_t.cpp
字号:
//---------------------------------------------------------------------------
#include "ArWinThreadPool_T.h"
#include "ArWinThread_T.h"
#include <process.h>
#include <stdio.h>
//---------------------------------------------------------------------------
ArWinThreadPool_T::ArWinThreadPool_T(int iInitialNum, int iStep)
{
//::InitializeCriticalSection(&m_csAllocate);
//::InitializeCriticalSection(&m_csFree);
m_hWatchEvent = ::CreateEvent(NULL, true, true, NULL);
ArWinThread_T::AllocateHeap();
m_iPoolNoUse = m_iInitialNum;
m_hHeap = ::HeapCreate(0, 1024, 0);
Initial(iInitialNum, iStep);
m_iPoolUsed = 0;
m_iPoolLastUsed = 0;
m_iCycleThread = 0;
m_iAdjustAdd = 0;
m_iAdjustSub = 0;
m_iUsedNumLastTime = 0;
m_pUsedFirst = NULL;
m_pUsedLast = NULL;
unsigned int uiThreadID;
m_ulCheckThread = _beginthreadex(NULL, 0, ThreadCheck,(void*)this, CREATE_SUSPENDED, &uiThreadID);
::SetThreadPriority((void*)m_ulCheckThread, THREAD_PRIORITY_IDLE);
::ResumeThread((void*)m_ulCheckThread);
};
//---------------------------------------------------------------------------
ArWinThreadPool_T::~ArWinThreadPool_T()
{
//::DeleteCriticalSection(&m_csAllocate);
//::DeleteCriticalSection(&m_csFree);
::TerminateThread((void*)m_ulCheckThread, 0);
ArWinThread_T::DestroyHeap();
::CloseHandle(m_hWatchEvent);
}
//---------------------------------------------------------------------------
bool __stdcall ArWinThreadPool_T::GetVersion(char* strVersion)
{
sprintf(strVersion, "线程池模块V1.0 开发人:杨朝霖");
return true;
}
//---------------------------------------------------------------------------
ArWinThread_T* ArWinThreadPool_T::Allocate(int iGrade)
{
ArWinThread_T* pThread;
//EnterCriticalSection(&m_csAllocate);
::WaitForSingleObject(m_hWatchEvent, INFINITE);
::ResetEvent(m_hWatchEvent);
/* if(0 == iGrade)
{
if(m_iPoolNoUse < MAX_NORMAL_NUM )
{
//LeaveCriticalSection(&m_csAllocate);
::SetEvent(m_hWatchEvent);
return NULL;
}
}*/
if(m_iPoolNoUse <= 1)
{
ExpandList();
}
if(NULL == m_pUsedFirst)
{
m_pNoUseLast->pPrior->pNext = m_pNoUseLast->pNext;
m_pUsedFirst = m_pNoUseLast;
m_pNoUseLast = m_pNoUseLast->pPrior;
m_pUsedFirst->pPrior = NULL;
m_pUsedLast = m_pUsedFirst;
m_pUsedLast->pNext = NULL;
}
else
{
ArThreadNode_T* pThreadNode = m_pNoUseLast;
m_pNoUseLast = m_pNoUseLast->pPrior;
m_pNoUseLast->pNext = pThreadNode->pNext;
pThreadNode->pNext = m_pUsedLast->pNext;
m_pUsedLast->pNext = pThreadNode;
pThreadNode->pPrior = m_pUsedLast;
m_pUsedLast = pThreadNode;
}
m_iPoolNoUse--;
m_iPoolUsed++;
pThread = m_pUsedLast->pThread;
//LeaveCriticalSection(&m_csAllocate);
::SetEvent(m_hWatchEvent);
return pThread;
}
//---------------------------------------------------------------------------
bool ArWinThreadPool_T::Free(ArWinThread_T* pThread)
{
::WaitForSingleObject(m_hWatchEvent, INFINITE);
::ResetEvent(m_hWatchEvent);
//EnterCriticalSection(&m_csFree);
ArThreadNode_T* pNode = FindeNode(pThread);
if(pNode == NULL)
{
//LeaveCriticalSection(&m_csFree);
::SetEvent(m_hWatchEvent);
return false;
}
pNode->pThread->Destory();
pNode->pThread = new ArWinThread_T(this);
Free(pNode);
if(pThread->IsCycle())
{
--m_iCycleThread;
}
//LeaveCriticalSection(&m_csFree);
::SetEvent(m_hWatchEvent);
return true;
}
//---------------------------------------------------------------------------
bool ArWinThreadPool_T::Free(ArThreadNode_T* pNode)
{
if(NULL == pNode->pNext && NULL == pNode->pPrior)
{
m_pUsedLast = NULL;
m_pUsedFirst = NULL;
}
else
{
if(NULL == pNode->pNext)
{
m_pUsedLast = pNode->pPrior;
if(m_pUsedLast->pNext)
{
m_pUsedLast->pNext = NULL;
}
}
if(NULL == pNode->pPrior)
{
m_pUsedFirst = pNode->pNext;
if(m_pUsedFirst->pPrior)
{
m_pUsedFirst->pPrior= NULL;
}
}
}
if(pNode->pPrior && pNode->pNext)
{
pNode->pPrior->pNext = pNode->pNext;
pNode->pNext->pPrior = pNode->pPrior;
}
//----------AddTo NoUseList--------------------
pNode->pNext = m_pNoUseLast->pNext;
m_pNoUseLast->pNext = pNode;
pNode->pPrior = m_pNoUseLast;
m_pNoUseLast = pNode;
m_iPoolNoUse++;
m_iPoolUsed--;
return true;
}
//---------------------------------------------------------------------------
bool __stdcall ArWinThreadPool_T::Initial(int iSize, int iStep)
{
m_iInitialNum = iSize;
m_iStep = iStep;
for(int iIndex = 0; iIndex < m_iInitialNum; iIndex++)
{
ArThreadNode_T* pNode = (ArThreadNode_T*)::HeapAlloc(m_hHeap, 0,sizeof(ArThreadNode_T));
ArWinThread_T* pThread = new ArWinThread_T(this);
pNode->pThread = pThread;
if(0 == iIndex)
{
m_pNoUseFirst = pNode;
m_pNoUseFirst->pPrior = NULL;
m_pNoUseLast = pNode;
m_pNoUseLast->pNext = NULL;
}
else
{
pNode->pNext = m_pNoUseLast->pNext;
pNode->pPrior = m_pNoUseLast;
m_pNoUseLast->pNext = pNode;
m_pNoUseLast = pNode;
}
}
m_iPoolNoUse = iSize;
return false;
}
//---------------------------------------------------------------------------
void __stdcall ArWinThreadPool_T::Destory(void)
{
TerminateAll();
delete this;
}
//---------------------------------------------------------------------------
ArThread_T* __stdcall ArWinThreadPool_T::GetThread(int iGrade, bool bCyc)
{
ArWinThread_T* pThread = Allocate(iGrade);
if(NULL == pThread)
{
return pThread;
}
pThread->SetType(bCyc);
pThread->SetGrade(iGrade);
if(bCyc)
{
m_iCycleThread++;
}
return pThread;
}
//---------------------------------------------------------------------------
bool __stdcall ArWinThreadPool_T::Free(ArThread_T* pThread)
{
ArWinThread_T* pWinThread = (ArWinThread_T*)pThread;
Free(pWinThread);
return true;
};
//---------------------------------------------------------------------------
bool __stdcall ArWinThreadPool_T::GetInfo(ArThreadPoolInfo_T &info)
{
info.iSize = m_iPoolNoUse + m_iPoolUsed;
info.iStep = m_iStep;
info.iThreadFree = m_iPoolNoUse;
info.iThreadUsed = m_iPoolUsed;
info.iThreadCyc = m_iCycleThread;
info.iAdjustAdd = m_iAdjustAdd;
info.iAdjustSub = m_iAdjustSub;
return true;
}
//---------------------------------------------------------------------------
ArThreadNode_T* ArWinThreadPool_T::FindeNode(ArWinThread_T* pThread)
{
ArThreadNode_T* pNode = m_pUsedFirst;
while(pNode)
{
if(pNode->pThread == pThread)
{
return pNode;
}
pNode = pNode->pNext;
}
return NULL;
}
//---------------------------------------------------------------------------
bool __stdcall ArWinThreadPool_T::TerminateAll(void)
{
ArThreadNode_T* pNode = m_pUsedFirst;
while(pNode)
{
pNode->pThread->Destory();
pNode = pNode->pNext;
}
pNode = m_pNoUseFirst;
while(pNode)
{
pNode->pThread->Destory();
pNode = pNode->pNext;
}
return true;
}
//---------------------------------------------------------------------------
void ArWinThreadPool_T::ExpandList(void)
{
//EnterCriticalSection(&m_csFree);
int iExpandNum = m_iStep + 1;
ArThreadNode_T* pFirst;
ArThreadNode_T* pLast;
for(int i = 0; i < iExpandNum; i++)
{
ArThreadNode_T* pNode = (ArThreadNode_T*)::HeapAlloc(m_hHeap, 0,sizeof(ArThreadNode_T));
ArWinThread_T* pThread = new ArWinThread_T(this);
pNode->pThread = pThread;
if(i == 0)
{
pFirst = pNode;
pFirst->pPrior = NULL;
pFirst->pNext = NULL;
pLast = pFirst;
}
else
{
pNode->pPrior = pLast;
pNode->pNext = pLast->pNext;
pLast->pNext = pNode;
pLast = pNode;
}
}
m_pNoUseLast->pNext = pLast->pNext;
m_pNoUseLast->pPrior = pLast;
pLast->pNext = m_pNoUseLast;
m_pNoUseFirst = pFirst;
m_iPoolNoUse = iExpandNum;
m_iAdjustAdd++;
// LeaveCriticalSection(&m_csFree);
};
//--------------------------------------------------------------------------
unsigned int __stdcall ArWinThreadPool_T::ThreadCheck(void* pPara)
{
ArWinThreadPool_T* pParent = (ArWinThreadPool_T*)pPara;
while(true)
{
pParent->CheckThreadPool();
Sleep(1000);
}
};
//--------------------------------------------------------------------------
void ArWinThreadPool_T::CheckThreadPool(void)
{
::WaitForSingleObject(m_hWatchEvent, INFINITE);
::ResetEvent(m_hWatchEvent);
// CheckBlockThread();
CheckUsedNum();
::SetEvent(m_hWatchEvent);
}
//--------------------------------------------------------------------------
void ArWinThreadPool_T::CheckBlockThread(void)
{
DWORD dwCurrTime = ::GetTickCount();
ArThreadNode_T* pNode = m_pUsedFirst;
while(pNode)
{
ArThreadNode_T* pNextNode;
DWORD dwLastTime = dwCurrTime - pNode->pThread->GetStartTime();
pNextNode = pNode->pNext ;
if(pNode->pThread->GetGrade() == 0)
{
if(dwLastTime > 20 * MAXTIME)
{
pNode->pThread->Destory();
pNode->pThread = new ArWinThread_T(this);
Free(pNode);
}
}
if(pNode->pThread->GetGrade() == 1)
{
if(dwLastTime > (200 * MAXTIME))
{
pNode->pThread->Destory();
pNode->pThread = new ArWinThread_T(this);
Free(pNode);
}
}
pNode = pNextNode;
}
};
//--------------------------------------------------------------------------
void ArWinThreadPool_T::CheckUsedNum(void)
{
int iPoolUsed = m_iPoolUsed;
int iOffset = abs(m_iPoolLastUsed - iPoolUsed);
if( iOffset > m_iStep)
{
m_iUsedNumLastTime = 0;
}
else
{
// if(iPoolUsed)
{
m_iUsedNumLastTime++;
if(m_iUsedNumLastTime > MAX_USED_NUM_TIME)
{
Substract();
m_iUsedNumLastTime = 0;
}
}
}
m_iPoolLastUsed = iPoolUsed;
}
//--------------------------------------------------------------------------
void ArWinThreadPool_T::Substract(void)
{
// EnterCriticalSection(&m_csFree);
// EnterCriticalSection(&m_csAllocate);
if(m_iPoolNoUse > (8 + MAX_NORMAL_NUM))
{
int SubstractNum = m_iPoolNoUse - (8 + MAX_NORMAL_NUM);
ArThreadNode_T* pNode;
for(int i = 0; i < SubstractNum; i++)
{
pNode = m_pNoUseLast;
pNode->pPrior->pNext = pNode->pNext;
m_pNoUseLast = pNode->pPrior;
pNode->pThread->Destory();
::HeapFree(m_hHeap,0, pNode);
m_iPoolNoUse--;
}
m_iAdjustSub++;
}
//LeaveCriticalSection(&m_csAllocate);
//LeaveCriticalSection(&m_csFree);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -