/*------------------------------------------------------------------
// 著作版权:Copyright (C) NST
// 创建时间:[Liuxb|20110914]
// 功能描述:线程池框架,任务基类
//
// 修改时间:
// 修改描述:
//
//----------------------------------------------------------------*/
#pragma once
#ifndef _THREADPOOL_H_
#define _THREADPOOL_H_
#include "stdafx.h"
#include <vector>
typedef void (WINAPI* ThreadProc)(DWORD);
void WINAPI ThreadProcess(DWORD i);
typedef struct tagTPINFO
{
HANDLE hio;
ThreadProc pThreadProc;
ULONG nNum;
} TPINFO,*PTPINFO;
DWORD WINAPI ThreadPoolProc(LPVOID lpPara);
BOOL WINAPI AddThreadJob(PTPINFO ptInfo,DWORD num);
void WINAPI CloseThreadPool(PTPINFO ptInfo);
PTPINFO WINAPI CreateThreadPool(ThreadProc pThreadProc,ULONG tNum,PTPINFO ptinfo);
namespace _Liuxb
{
///工作基类
class IWork
{
public:
//virtual ~IWork() = 0;
///工作运行
virtual void Running() = 0;
};
///工作队列
class WorkQueue
{
public:
static WorkQueue* Instance()
{
if(_pInstance==0)
{
if(!_destroyed)
{
throw std::runtime_error("Error:WorkQueueSingleton::Instance was destroyed");
}
static WorkQueue theInstance;
_pInstance = &theInstance;
}
return _pInstance;
}
~WorkQueue()
{
DeleteCriticalSection(&_cs);
}
private:
WorkQueue()
{
::InitializeCriticalSection(&_cs);
}
WorkQueue(const WorkQueue& workqueue)
{
}
WorkQueue operator =(const WorkQueue& workqueue)
{
}
public:
void AddWork(IWork* pWork)
{
_vecWork.push_back(pWork);
}
IWork* GetAndPopBackWork()
{
::EnterCriticalSection(&_cs);
IWork* pWork = NULL;
if(!_vecWork.empty())
{
pWork = _vecWork.back();
_vecWork.pop_back();
}
::LeaveCriticalSection(&_cs);
return pWork;
}
private:
std::vector<IWork*> _vecWork;
CRITICAL_SECTION _cs;
static WorkQueue* _pInstance;
static BOOL _destroyed;
};
}
#endif
#include "StdAfx.h"
#include "ThreadPool.h"
using namespace _Liuxb;
BOOL WorkQueue::_destroyed = TRUE;
WorkQueue* WorkQueue::_pInstance = NULL;
///完成端口上接收任务
DWORD WINAPI ThreadPoolProc(LPVOID lpPara)
{
DWORD bytes = 0;
DWORD key = 0;
LPOVERLAPPED ove;
PTPINFO ptinfo = (PTPINFO)lpPara;
while(GetQueuedCompletionStatus(ptinfo->hio,&bytes,&key,&ove,INFINITE))
{
if(-1==bytes)
{
break;
}
ptinfo->pThreadProc(bytes);
}
return 0;
}
///添加任务
BOOL WINAPI AddThreadJob(PTPINFO ptInfo,DWORD num)
{
if(!ptInfo)
return false;
return PostQueuedCompletionStatus(ptInfo->hio,num,-1,(LPOVERLAPPED)-1);
}
///关闭完成端口
void WINAPI CloseThreadPool(PTPINFO ptInfo)
{
if(!ptInfo)
return;
for(unsigned int i=0;i<ptInfo->nNum;i++)
{
PostQueuedCompletionStatus(ptInfo->hio,-1,-1,(LPOVERLAPPED)-1);
}
WaitForSingleObject(ptInfo->hio,INFINITE);
CloseHandle(ptInfo->hio);
delete ptInfo;
}
///创建完成端口
PTPINFO WINAPI CreateThreadPool(ThreadProc pThreadProc,ULONG tNum,PTPINFO ptinfo)
{
if(!tNum || !pThreadProc)
tNum+=5;
ptinfo->hio=CreateIoCompletionPort((HANDLE)-1,NULL,0,0);
if(!ptinfo->hio)
{
CloseHandle(ptinfo->hio);
delete ptinfo;
return (PTPINFO)0;
}
ptinfo->nNum=tNum;
ptinfo->pThreadProc=pThreadProc;
for(unsigned int i=0;i<ptinfo->nNum;i++)
{
CloseHandle(CreateThread(NULL,0,ThreadPoolProc,(PVOID)ptinfo,0,NULL));
}
return ptinfo;
}
///任务执行
void WINAPI ThreadProcess(DWORD i)
{
_Liuxb::WorkQueue* pWorkQueue = _Liuxb::WorkQueue::Instance();
_Liuxb::IWork* pWork = pWorkQueue->GetAndPopBackWork();
if(pWork)
{
pWork->Running();
}
}