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>