#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++; } }