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 c
lass 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?
<pre lang="C++">
class ThreadModel
{
public:
BOOL StartThread();
void StopThread();
BOOL WaitThread(DWORD nTimeOut = INFINITE); protected:
virtual void BeforeThread();
virtual void AfterThread();
virtual UINT Run() = 0;
protected:
BOOL QueryExitEvent(DWORD dwDuration = 0);
BOOL IsThreadRunning() { return (m_hThread != 0); }
private:
static UINT __stdcall __ThreadProxyProc(LPVOID pParam);
protected:
ThreadModel();
virtual ~ThreadModel();
protected:
HANDLE m_hThread;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;
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);
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)
{
::SetEvent(m_hEvtUserAbort);
if (::WaitForSingleObject(m_hEvtThreadOver, 5 * 1000) == WAIT_OBJECT_0)
{
::ResetEvent(m_hEvtThreadOver);
}
else
{
::TerminateThread(m_hThread, 1);
m_hThread = NULL;
}
}
else
::ResetEvent(m_hEvtThreadOver);
}
3.Wait thread over
BOOL ThreadModel::WaitThread(DWORD nTimeOut )
{
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?
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()<br />{<br />while(QueryExitEvent() == FALSE)<br />{<br />printf("%s\n","thread is running");<br />::Sleep(10);<br />}<br />return 0;<br />}</p>
<p>UINT ThreadSample2::Run()<br />{<br />for(int i = 0; i< 100; i++)<br />{<br />::Sleep(100);<br />printf("the thread2 is running\n");<br />}<br />return 0;<br />}</p>
<p><br />int _tmain(int argc, _TCHAR* argv[])<br />{<br />
<p>
<p>return 0;<br />}</p>
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.