#include "stdafx.h"
#include "tasks.h"
#include "worker.h"
#define THREADPOOL_SIZE 5
///
int main(int /*argc*/, char* /*argv[]*/)
{
CThreadPool 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;
}
// File: tasks.h
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Classes Reference and related electronic
// documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft C++ Libraries products.
#pragma once
///
class CTaskBase
{
public:
virtual void DoTask(void *pvParam, OVERLAPPED *pOverlapped)=0;
};
///
class CTask1 : public CTaskBase
{
public:
virtual void DoTask(void *pvParam, OVERLAPPED *pOverlapped)
{
printf("[%d]: CTask1::DoTask(pvParam=%d, pOverlapped=%d)\n",
::GetCurrentThreadId(), (DWORD_PTR)pvParam, (DWORD_PTR)pOverlapped);
}
};
///
class CTask2 : public CTaskBase
{
public:
virtual void DoTask(void *pvParam, OVERLAPPED *pOverlapped)
{
printf("[%d]: CTask2::DoTask(pvParam=%d, pOverlapped=%d)\n",
::GetCurrentThreadId(), (DWORD_PTR)pvParam, (DWORD_PTR)pOverlapped);
}
};
///
typedef CSimpleArray CTaskArray;
///
bool CreateTasks(CTaskArray& tasks, DWORD dwCount)
{
bool bOk = false;
if ( 0 == tasks.GetSize() && dwCount > 0 ) {
CTaskBase* pTask = NULL;
for ( DWORD i = 0; i < dwCount; i++ ) {
if ( i % 2 )
pTask = new CTask1;
else
pTask = new CTask2;
if ( !tasks.Add( pTask ))
ATLASSERT( false );
}
bOk = true;
}
return bOk;
}
/ File: Worker.h
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Classes Reference and related electronic
// documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft C++ Libraries products.
#pragma once
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