Click here to Skip to main content
Click here to Skip to main content
Go to top

A thread wrapper class

, 12 Apr 2007
Rate this:
Please Sign up or sign in to vote.
A wrapper class of worker thread

Introduction

As a C++ programmer in Windows platform, I often use worker thread to deal with some tasks. For example I need to keep the GUI active while a computation is being performed.

But it isn't easy to implement the special synchronization feature for program beginner. To solve the problem, I write the ThreadModel class. The class written in Microsoft Visual C++ is a wrapper class that can control worker thread running exactly, such as Start, Stop and Wait thread until it is ended.

How is it working?

Screenshot - 1.jpg

<pre lang="C++">// -----------
//  ThreadModel

// ------------
class  ThreadModel  
{
public:
//---------------------
// functions that be used to control the thread running.
//---------------------
// start the thread
BOOL StartThread();
// stop the thread
void StopThread(); 
BOOL WaitThread(DWORD nTimeOut = INFINITE); // virtual function
protected:
//---------------------
// override functions
//---------------------
virtual void BeforeThread();
virtual void AfterThread(); 
// the thread function
virtual UINT Run() = 0;
protected:
/// Query if the the method "stop thread" has been executed.the paramater "dwDuration" is waiting time
/// if it is "0",the method will return at once.
BOOL QueryExitEvent(DWORD dwDuration = 0);
/// Query the the thread if existing 
BOOL IsThreadRunning() { return (m_hThread != 0); }
private:
/// the static thread function
static UINT __stdcall __ThreadProxyProc(LPVOID pParam);
protected:
ThreadModel();
virtual ~ThreadModel();
protected:
HANDLE m_hThread;//<the handle of thread
private:
BOOL m_bLowCpuPriority; //<
HANDLE m_hEvtThreadStart; //< 
HANDLE m_hEvtThreadOver; //<
HANDLE m_hEvtUserAbort; //<
};
1.StartThread
BOOL ThreadModel::StartThread()
{
if (m_hThread != NULL) return FALSE;
::ResetEvent(m_hEvtUserAbort);
::ResetEvent(m_hEvtThreadOver);
UINT nThreadID = 0;
//start the new worker thread
int nVal = _beginthreadex(NULL, 0, __ThreadProxyProc, (void *)this, 0, &nThreadID);
if(nVal <= 0) 
{
return FALSE;
}
m_hThread = reinterpret_cast<HANDLE>(nVal);
if (m_bLowCpuPriority)
SetThreadPriority(m_hThread, THREAD_PRIORITY_IDLE);
// wait thread start
DWORD nWait = ::WaitForSingleObject(m_hEvtThreadStart, INFINITE);
::ResetEvent(m_hEvtThreadStart);
if (nWait != WAIT_OBJECT_0)
return FALSE;
return TRUE;
}
2.Stop thread
void ThreadModel::StopThread()
{ 
if (m_hThread != NULL)
{ 
// try to Stop thread
::SetEvent(m_hEvtUserAbort);
// default wait 5 secs
if (::WaitForSingleObject(m_hEvtThreadOver, 5 * 1000) == WAIT_OBJECT_0)
{
// ok . 
::ResetEvent(m_hEvtThreadOver);
}
else 
{ 
// kill thread,but it is dangerous
::TerminateThread(m_hThread, 1);
m_hThread = NULL;
} 
}
else
::ResetEvent(m_hEvtThreadOver);
}
3.Wait thread over
BOOL ThreadModel::WaitThread(DWORD nTimeOut /*= INFINITE*/)
{
if (NULL == m_hThread)
return FALSE;
BOOL result = (WaitForSingleObject(m_hEvtThreadOver, nTimeOut) == WAIT_OBJECT_0)?true:false;
if (!result)
{
::TerminateThread(m_hThread, 1); 
m_hThread = NULL;
}
return result; 
}

How to use it?

Screenshot - 2.jpg

The ThreadModel Class provides two ways to use it.
1.the UI-thread create the worker thread, the worker thread is running until the UI-thread execute "StopThread" method to end the worker thread. The derived class ThreadSample1 show the way.
2.the UI-thread create the worker thread, and it will wait for the worker thread until it is over. The derived class ThreadSampl2 show how to implement it;

<p>UINT ThreadSample::Run()
{
while(QueryExitEvent() == FALSE)
{
printf("%s\n","thread is running");
::Sleep(10);
}
return 0;
}</p>

<p>UINT ThreadSample2::Run()
{
for(int i = 0; i< 100; i++)
{
::Sleep(100);
printf("the thread2 is running\n");
}
return 0;
}</p>

<p>
int _tmain(int argc, _TCHAR* argv[])
{
//the sample1 of thread
ThreadSample ts;
ts.StartThread();
::Sleep(10000);
//the main thread stop the working thread
ts.StopThread();
printf("the thread is over");</p>

<p>//the sample2 of thread
ThreadSample2 ts2;
ts2.StartThread();
//the main thread is waiting until the working is over
BOOL bRet = ts2.WaitThread();
{
printf("the thread2 is over");
}</p>

<p>return 0;
}</p>

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Bony Chen
Web Developer
China China
Bony Chen, a senior software engineer, specializes in C++, COM, C#, ASP.net, ISAPI. He has nearly seven years of software development experience, and has successfully developed many influential software products, such as SPES, CSO, QQ (a famous IM tool in China).
And now he is focusing on P2P technology. He aims at being an expert in software development, software consulting, software components and computer science.
If you have any opinions or questions in software area, please contact bonyren@163.com.

Comments and Discussions

 
GeneralName PinmemberMichael Holm12-Apr-07 20:38 
GeneralA few suggestions PinmemberAli Rafiee12-Apr-07 13:48 
GeneralRe: A few suggestions PinmemberBony Chen12-Apr-07 15:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 12 Apr 2007
Article Copyright 2007 by Bony Chen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid