ATL 线程池的使用
2011-07-16 20:45 Clingingboy 阅读(2357) 评论(0) 编辑 收藏 举报
一.自定义一个Worker
class CMyWorker
{
public:
typedef MyRequestType RequestType;
BOOL Initialize(void* pvWorkerParam);
void Execute(MyRequestType request, void* pvWorkerParam, OVERLAPPED* pOverlapped);
void Terminate(void* pvWorkerParam);
};
必须实现以上接口
具体参考如下:
http://msdn.microsoft.com/zh-cn/library/ytkt93h8.aspx
Demo:
LONG g_lCurrId = -1;
class CMyWorker
{
public:
typedef DWORD_PTR RequestType;
CMyWorker() : m_dwExecs( 0 )
{
m_lId = InterlockedIncrement( &g_lCurrId );
}
virtual BOOL Initialize(void *pvParam)
{
printf("[%d]: CMyWorker.Initialize(%d)\n", (DWORD_PTR)::GetCurrentThreadId(), (DWORD_PTR)pvParam );
return TRUE;
}
virtual void Terminate(void* /*pvParam*/)
{
printf( "CMyWorker #%d exec'd %d times.\n", m_lId, m_dwExecs );
}
void Execute(RequestType dw, void *pvParam, OVERLAPPED* pOverlapped) throw()
{
ATLASSERT(pvParam != NULL);
printf("[%d] CMyWorker::Execute(dw=%d, pvParam=%d, pOverlapped=%d\n",
::GetCurrentThreadId(), dw, (DWORD_PTR)pvParam, (DWORD_PTR)pOverlapped);
CTaskBase* pTask = (CTaskBase*)(DWORD_PTR)dw;
pTask->DoTask(pvParam, pOverlapped);
m_dwExecs++;
}
virtual BOOL GetWorkerData(DWORD /*dwParam*/, void ** /*ppvData*/)
{
return FALSE;
}
protected:
DWORD m_dwExecs;
LONG m_lId;
}; // CMyWorker
二.线程池(CThreadPool)
#define THREADPOOL_SIZE 5
///////////////////////////////////////////////////////////////////////////////
int main(int /*argc*/, char* /*argv[]*/)
{
CThreadPool<CMyWorker> pool;
CTaskArray tasks;
HRESULT hr = pool.Initialize((void*)321, THREADPOOL_SIZE);
if( SUCCEEDED( hr ) ) {
int i = -1;
CTaskBase* pTask = NULL;
if ( CreateTasks(tasks, 100) ) {
for ( i = 0; i < tasks.GetSize(); i++ ) {
pTask = tasks[ i ];
ATLASSERT( NULL != pTask );
pool.QueueRequest( (CMyWorker::RequestType) pTask );
}
}
// Allow a little time for all the tasks to complete
Sleep(1000);
// Clean up the tasks and shutdown the thread pool
for ( i = 0; i < tasks.GetSize(); i++ ) {
pTask = tasks[ i ];
ATLASSERT( NULL != pTask );
delete pTask;
}
// Shutdown the thread pool
pool.Shutdown();
}
else
printf("Failed to init thread pool!");
printf("\n");
return 0;
}
参考:http://msdn.microsoft.com/zh-cn/library/dta23y51.aspx
- Initialize初始化线程数量,并初始化Worker
- QueueRequest则调用Worker的Execute方法
- 等Worker全部执行完毕以后才调用Terminate方法
三.IThreadPoolConfig
定义了一个基础的接口
// Used to configure the worker thread pool. This can be used by any
// client of the CThreadPool class.
__interface __declspec(uuid("B1F64757-6E88-4fa2-8886-7848B0D7E660"))
IThreadPoolConfig : public IUnknown
{
STDMETHOD(SetSize)(_In_ int nNumThreads);
STDMETHOD(GetSize)(_Out_ int *pnNumThreads);
STDMETHOD(SetTimeout)(_In_ DWORD dwMaxWait);
STDMETHOD(GetTimeout)(_Out_ DWORD *pdwMaxWait);
};
四.ThreadTraits
分两种CRTThreadTraits和Win32ThreadTraits,分别调用_beginthreadex和CreateThread方法
五.WaitTraits
只实现了Win32WaitTraits了,即调用了WaitForSingleObject