线程池例程
来源:互联网 发布:北京二手房成交数据 编辑:程序博客网 时间:2024/05/17 09:11
- 类定义如下
- #if !defined(AFX_THREADPOOLIMP_H__82F4FC7E_2DB4_4D2A_ACC8_2EFC787CAE42__INCLUDED_)
- #define AFX_THREADPOOLIMP_H__82F4FC7E_2DB4_4D2A_ACC8_2EFC787CAE42__INCLUDED_
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- #pragma warning( disable : 4705 4786)
- #include <map>
- #include "AutoLock.h"
- using namespace std;
- class IJobDesc;
- class IWorker;
- class CThreadPoolImp
- {
- public:
- class ThreadInfo
- {
- public:
- ThreadInfo() { m_hThread=0; m_bBusyWorking=false; }
- ThreadInfo(HANDLE handle, bool bBusy) { m_hThread=handle; m_bBusyWorking=bBusy; }
- ThreadInfo(const ThreadInfo& info) { m_hThread=info.m_hThread; m_bBusyWorking=info.m_bBusyWorking; }
- HANDLE m_hThread;
- boolm_bBusyWorking;
- };
- typedef map<DWORD,ThreadInfo> ThreadInfoMap;
- typedef ThreadInfoMap::iterator Iterator_ThreadInfoMap;
- friend static unsigned int CThreadPoolImp::ManagerProc(void* p);
- friend static unsigned int CThreadPoolImp::WorkerProc(void* p);
- protected:
- enum ThreadPoolStatus { BUSY, IDLE, NORMAL };
- public:
- void Start(unsigned short nStatic, unsigned short nmax);
- void Stop(bool bHash=false);
- void ProcessJob(IJobDesc* pJob, IWorker* pWorker) const;
- CThreadPoolImp();
- virtual ~CThreadPoolImp();
- protected:
- HANDLE GetMgrIoPort() const { return m_hMgrIoPort; }
- UINT GetMgrWaitTime() const { return 1000; }
- HANDLE GetWorkerIoPort() const { return m_hWorkerIoPort; }
- private:
- static DWORD WINAPI ManagerProc(void* p);
- static DWORD WINAPI WorkerProc(void* p);
- protected:
- HANDLE m_hMgrThread;
- HANDLE m_hMgrIoPort;
- protected:
- mutable unsigned short m_nNumberOfStaticThreads;
- mutable unsigned short m_nNumberOfTotalThreads;
- protected:
- void AddThreads();
- void RemoveThreads();
- ThreadPoolStatus GetThreadPoolStatus();
- void ChangeStatus(DWORD threadId, bool status);
- void RemoveThread(DWORD threadId);
- protected:
- ThreadInfoMap m_threadMap;
- CCriticalSection m_arrayCs;
- HANDLE m_hWorkerIoPort;
- };
- #endif // !defined(AFX_THREADPOOLIMP_H__82F4FC7E_2DB4_4D2A_ACC8_2EFC787CAE42__INCLUDED_)
- 实现如下
- #include "stdafx.h"
- #include "ThreadPoolimp.h"
- #include "outdebug.h"
- #include <assert.h>
- #include "work.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #endif
- CThreadPoolImp::CThreadPoolImp()
- {
- }
- CThreadPoolImp::~CThreadPoolImp()
- {
- }
- void CThreadPoolImp::Start(unsigned short nStatic, unsigned short nMax)
- {
- assert(nMax>=nStatic);
- HANDLE hThread;
- DWORDnThreadId;
- m_nNumberOfStaticThreads=nStatic;
- m_nNumberOfTotalThreads=nMax;
- CAutoLock AutoLock(m_arrayCs);
- m_hMgrIoPort = CreateIoCompletionPort((HANDLE)INVALID_HANDLE_VALUE, NULL, 0, 0);
- hThread = CreateThread(
- NULL,
- 0,
- (LPTHREAD_START_ROUTINE)ManagerProc,
- (LPVOID)this,
- 0,
- &nThreadId );
- m_hMgrThread = hThread;
- m_hWorkerIoPort = CreateIoCompletionPort((HANDLE)INVALID_HANDLE_VALUE, NULL, 0, 0);
- for(long n = 0; n < nStatic; n )
- {
- hThread = CreateThread(
- NULL,
- 0,
- (LPTHREAD_START_ROUTINE)WorkerProc,
- (LPVOID)this,
- 0,
- &nThreadId );
- ReportDebug("generate a worker thread handle id is d./n", nThreadId);
- m_threadMap.insert(m_threadMap.end(),ThreadInfoMap::value_type(nThreadId,ThreadInfo(hThread, false)));
- }
- }
- void CThreadPoolImp::Stop(bool bHash)
- {
- CAutoLock Lock(m_arrayCs);
- ::PostQueuedCompletionStatus(m_hMgrIoPort, 0, 0, (OVERLAPPED*)0xFFFFFFFF);
- WaitForSingleObject(m_hMgrThread, INFINITE);
- CloseHandle(m_hMgrThread);
- CloseHandle(m_hMgrIoPort);
- UINT nCount=m_threadMap.size();
- HANDLE* pThread = new HANDLE[nCount];
- long n=0;
- ThreadInfo info;
- Iterator_ThreadInfoMap i=m_threadMap.begin();
- while(i!=m_threadMap.end())
- {
- ::PostQueuedCompletionStatus(m_hWorkerIoPort, 0, 0, (OVERLAPPED*)0xFFFFFFFF);
- info=i->second;
- pThread[n ]=info.m_hThread;
- i ;
- }
- DWORD rc=WaitForMultipleObjects(nCount, pThread, TRUE, 30000);
- CloseHandle(m_hWorkerIoPort);
- if(rc>=WAIT_OBJECT_0 && rc<WAIT_OBJECT_0 nCount)
- {
- for(unsigned int n=0;n<nCount;n )
- {
- CloseHandle(pThread[n]);
- }
- }
- else if(rc==WAIT_TIMEOUT&&bHash)
- {
- DWORD exitCode;
- for(unsigned int i=0; i<nCount; i )
- {
- if (::GetExitCodeThread(pThread[i], &exitCode)==STILL_ACTIVE)
- {
- TerminateThread(pThread[i], 99);
- }
- CloseHandle(pThread[i]);
- }
- }
- delete[] pThread;
- }
- DWORD WINAPI CThreadPoolImp::ManagerProc(void* p)
- {
- CThreadPoolImp* pServer=(CThreadPoolImp*)p;
- HANDLEIoPort= pServer->GetMgrIoPort();
- unsigned longpN1, pN2;
- OVERLAPPED*pOverLapped;
- LABEL_MANAGER_PROCESSING:
- while(::GetQueuedCompletionStatus(IoPort, &pN1, &pN2,
- &pOverLapped, pServer->GetMgrWaitTime() ))
- {
- if(pOverLapped == (OVERLAPPED*)0xFFFFFFFF)
- {
- return 0;
- }
- else
- {
- ReportDebug("mgr events comes in!/n");
- }
- }
- if (::GetLastError()==WAIT_TIMEOUT)
- {
- ReportDebug("Time out processing!/n");
- if (pServer->GetThreadPoolStatus()==CThreadPoolImp::BUSY)
- pServer->AddThreads();
- if (pServer->GetThreadPoolStatus()==CThreadPoolImp::IDLE)
- pServer->RemoveThreads();
- goto LABEL_MANAGER_PROCESSING;
- }
- return 0;
- }
- DWORD WINAPI CThreadPoolImp::WorkerProc(void* p)
- {
- CThreadPoolImp* pServer=(CThreadPoolImp*)p;
- HANDLEIoPort= pServer->GetWorkerIoPort();
- unsigned longpN1, pN2;
- OVERLAPPED*pOverLapped;
- DWORD threadId=::GetCurrentThreadId();
- ReportDebug("worker thread id is d./n", threadId);
- while(::GetQueuedCompletionStatus(IoPort, &pN1, &pN2,
- &pOverLapped, INFINITE ))
- {
- if(pOverLapped == (OVERLAPPED*)0xFFFFFFFE)
- {
- pServer->RemoveThread(threadId);
- break;
- }
- else if(pOverLapped == (OVERLAPPED*)0xFFFFFFFF)
- {
- break;
- }
- else
- {
- ReportDebug("worker events comes in!/n");
- pServer->ChangeStatus(threadId, true);
- IWorker* pIWorker = reinterdivt_cast<IWorker*>(pN1);
- IJobDesc* pIJob= reinterdivt_cast<IJobDesc*>(pN2);
- pIWorker->ProcessJob(pIJob);
- pServer->ChangeStatus(threadId, false);
- }
- }
- return 0;
- }
- void CThreadPoolImp::ChangeStatus(DWORD threadId, bool status)
- {
- CAutoLock CAutoLock(m_arrayCs);
- Iterator_ThreadInfoMap i;
- ThreadInfo info;
- i=m_threadMap.find(threadId);
- info=i->second;
- info.m_bBusyWorking=status;
- m_threadMap.insert(m_threadMap.end(),ThreadInfoMap::value_type(threadId, info));
- }
- void CThreadPoolImp::ProcessJob(IJobDesc* pJob, IWorker* pWorker) const
- {
- ::PostQueuedCompletionStatus(m_hWorkerIoPort, /
- reinterdivt_cast<DWORD>(pWorker), /
- reinterdivt_cast<DWORD>(pJob),/
- NULL);
- }
- void CThreadPoolImp::AddThreads()
- {
- HANDLE hThread;
- DWORDnThreadId;
- unsigned int nCount=m_threadMap.size();
- unsigned int nTotal=min(nCount 2, m_nNumberOfTotalThreads);
- for(unsigned int i=0; i<nTotal-nCount; i )
- {
- hThread = CreateThread(
- NULL,
- 0,
- (LPTHREAD_START_ROUTINE)WorkerProc,
- (LPVOID)this,
- 0,
- &nThreadId );
- ReportDebug("generate a worker thread handle id is d./n", nThreadId);
- m_threadMap.insert(m_threadMap.end(),ThreadInfoMap::value_type(nThreadId,ThreadInfo(hThread, false)));
- }
- }
- void CThreadPoolImp::RemoveThread(DWORD threadId)
- {
- CAutoLock lock(m_arrayCs);
- m_threadMap.erase(threadId);
- }
- void CThreadPoolImp::RemoveThreads()
- {
- unsigned int nCount=m_threadMap.size();
- unsigned int nTotal=max(nCount-2, m_nNumberOfStaticThreads);
- for(unsigned int i=0; i<nCount-nTotal; i )
- {
- ::PostQueuedCompletionStatus(m_hWorkerIoPort, 0, 0, (OVERLAPPED*)0xFFFFFFFE);
- }
- }
- CThreadPoolImp::ThreadPoolStatus CThreadPoolImp::GetThreadPoolStatus()
- {
- int nTotal = m_threadMap.size();
- ThreadInfo info;
- int nCount=0;
- Iterator_ThreadInfoMap i=m_threadMap.begin();
- while(i!=m_threadMap.end())
- {
- info=i->second;
- if (info.m_bBusyWorking==true) nCount ;
- i ;
- }
- if ( nCount/(1.0*nTotal) > 0.8 )
- return BUSY;
- if ( nCount/ (1.0*nTotal) < 0.2 )
- return IDLE;
- return NORMAL;
- }