165 lines
3.3 KiB
C++
165 lines
3.3 KiB
C++
#include "stdafx.h"
|
|
#include "WorkerThreadPool.h"
|
|
|
|
CWorkerThreadPool::CWorkerThreadPool() :
|
|
m_hIOCP(NULL),
|
|
m_dwThreadCount(0)
|
|
{
|
|
|
|
}
|
|
|
|
CWorkerThreadPool::~CWorkerThreadPool()
|
|
{
|
|
}
|
|
|
|
bool CWorkerThreadPool::CreateThreadPool(DWORD dwThreadCnt)
|
|
{
|
|
if(MAX_THREAD_COUNT < dwThreadCnt) //스레드 최대 생성 개수 이상 생성하려고 하면 실패
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_hIOCP = ::CreateIoCompletionPort( INVALID_HANDLE_VALUE, 0, 0, dwThreadCnt ); // 메인 IOCP 핸들 생성
|
|
|
|
if(NULL == m_hIOCP)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_dwThreadCount = dwThreadCnt;
|
|
UINT threadID = 0;
|
|
|
|
for(DWORD i = 0 ; i < m_dwThreadCount ; i++ ) // 작업 스레드를 생성한다.
|
|
{
|
|
m_hThread[i] = (HANDLE)_beginthreadex(0, 0, WorkThreadProc, (LPVOID)this, 0, &threadID);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
UINT __stdcall CWorkerThreadPool::WorkThreadProc( LPVOID lParam )
|
|
{
|
|
BOOL ret;
|
|
DWORD transBytes;
|
|
DWORD_PTR key;
|
|
OVERLAPPED result;
|
|
|
|
HANDLE hIOCP = ((CWorkerThreadPool*)lParam)->m_hIOCP;
|
|
|
|
::CoInitialize(NULL);
|
|
|
|
while(true)
|
|
{
|
|
ret = ::GetQueuedCompletionStatus( hIOCP, &transBytes, &key, (LPOVERLAPPED*)&result, INFINITE);
|
|
|
|
if(IOCPTHREAD_CLOSE == key) //종료신호를 받았을때
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
((CWorkerThread*)key)->Run();
|
|
}
|
|
}
|
|
|
|
::CoUninitialize();
|
|
|
|
return 0;
|
|
}
|
|
|
|
UINT __stdcall CWorkerThreadPool::SessionThreadProc( LPVOID parameter )
|
|
{
|
|
::CoInitialize(NULL);
|
|
|
|
if(NULL == ((CWorkerThread*)parameter)->GetExitEvent())
|
|
{
|
|
((CWorkerThread*)parameter)->RunProc();
|
|
}
|
|
else
|
|
{
|
|
while(true)
|
|
{
|
|
if(WaitForSingleObject(((CWorkerThread*)parameter)->GetExitEvent(), 1) == WAIT_OBJECT_0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
((CWorkerThread*)parameter)->RunProc();
|
|
}
|
|
}
|
|
|
|
::CoUninitialize();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CWorkerThreadPool::DestoryThreadPool()
|
|
{
|
|
if(NULL != m_hIOCP)
|
|
{
|
|
for (DWORD i = 0; i < m_dwThreadCount; i++)
|
|
{
|
|
PostQueuedCompletionStatus(m_hIOCP, 0, IOCPTHREAD_CLOSE, NULL); //스레드에 종료 메시지를 보낸다.
|
|
}
|
|
|
|
// 작업스레드들이 종료될때 까지 대기한다.
|
|
DWORD dwRet = WaitForMultipleObjects( m_dwThreadCount, m_hThread, TRUE, 2000);
|
|
|
|
// 메인 IOCP 핸들 닫기
|
|
CloseHandle(m_hIOCP);
|
|
m_hIOCP = NULL;
|
|
|
|
//스레드 핸들 닫기
|
|
for(DWORD i = 0 ; i < m_dwThreadCount ; i++ )
|
|
{
|
|
CloseHandle(m_hThread[i]);
|
|
}
|
|
m_dwThreadCount = 0;
|
|
}
|
|
}
|
|
|
|
BOOL CWorkerThreadPool::AddJob(CWorkerThread* pWorker)
|
|
{
|
|
if(NULL == m_hIOCP) return FALSE;
|
|
return PostQueuedCompletionStatus(m_hIOCP, 0, (DWORD_PTR)pWorker, NULL);
|
|
}
|
|
|
|
void CWorkerThreadPool::AddJobThread(CWorkerThread* pWorker)
|
|
{
|
|
//CWorkerThread* pWorker = new CWorkerThread;
|
|
UINT threadID = 0;
|
|
|
|
pWorker->SetExitEvent();
|
|
|
|
HANDLE hThread = (HANDLE)_beginthreadex(0, 0, SessionThreadProc, (LPVOID)pWorker, 0, &threadID);
|
|
|
|
pWorker->SetThreadHandle(hThread);
|
|
m_vecThread.push_back(pWorker);
|
|
}
|
|
|
|
void CWorkerThreadPool::AllStopJobThread()
|
|
{
|
|
while(m_vecThread.empty()==false) // worker thread 정리
|
|
{
|
|
CWorkerThread* pWorker = m_vecThread.back();
|
|
m_vecThread.pop_back();
|
|
pWorker->Terminate();
|
|
pWorker->WaitThread(250);
|
|
//delete pWorker;
|
|
pWorker = NULL;
|
|
}
|
|
}
|
|
|
|
void CWorkerThreadPool::OnTimr(HANDLE hRequest, DWORD dwRequest)
|
|
{
|
|
// 기본적으로 락처리를 해야 하지만, 정적으로 사용하는 구조라서 락처리를 따로 하지는 않는다.
|
|
WorkerIter Iter = m_vecThread.begin();
|
|
while(Iter != m_vecThread.end())
|
|
{
|
|
CWorkerThread* pWorker = (*Iter);
|
|
if(pWorker)
|
|
pWorker->OnTimer(hRequest, dwRequest);
|
|
|
|
Iter++;
|
|
}
|
|
} |