1.Creating Worker Thread
CWinThread *pThread=AfxBeginThread(ThreadFun,&ThreadInfo,0,CREATE_SUSPENDED);//创建,但不马上执行
...........
pThread->ResumeThread();//start the thread;
CWinThread *pThread=AfxBeginThread(ThreadFun,&ThreadInfo);//创建,马上执行
//The ThreadFun is a static number function or global function outside class,because thread function is a callback function.
2.Creating UI Thread
A worker thread is defined by its thread function, but a UI thread's behavior is governed by a dynamically creatable class derived from CWinThread that resembles an application class derived from CWinApp.
// The CUIThread class
class CUIThread : public CWinThread
{
DECLARE_DYNCREATE (CUIThread)
public:
virtual BOOL InitInstance ();
};
IMPLEMENT_DYNCREATE (CUIThread, CWinThread)
BOOL CUIThread::InitInstance ()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow (SW_SHOW);
m_pMainWnd->UpdateWindow ();
return TRUE;
}
// The CMainWindow class
class CMainWindow : public CFrameWnd
{
public:
CMainWindow ();
protected:
afx_msg void OnLButtonDown (UINT, CPoint);
DECLARE_MESSAGE_MAP ()
};
BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
ON_WM_LBUTTONDOWN ()
END_MESSAGE_MAP ()
CMainWindow::CMainWindow ()
{
Create (NULL, _T ("UI Thread Window"));
}
void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point)
{
PostMessage (WM_CLOSE, 0, 0);
}
You launch a CUIThread by calling the form of AfxBeginThread that accepts a CRuntimeClass pointer to the thread class:
CWinThread* pThread = AfxBeginThread (RUNTIME_CLASS (CUIThread));
The UI-thread version of AfxBeginThread accepts the same four optional parameters as the worker-thread version, but it doesn't accept a pParam value. Once started, a UI thread runs asynchronously with respect to the thread that created it.
3.Suspend and Resume Thread
CWinThread::SuspendThread CWinThread::ResumeThread //must match; the Thread itself can't resume it.
4.Terminate Thread
CWinThread *pThread=AfxBeginThread(ThreadFun ,NULL,THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
pThread->mAutoDelelte=FALSE;
pThread->ResumeThread();
UINT dwExitCode;
::GetExitCodeThread(pThread->m_hThread,&dwExitCode);
if(dwExitCode==STILL_ACTIVE) {
// The thread is still running.
}
else {
// The thread has terminated. Delete the CWinThread object.
delete pThread;
}
//The following have the same function with above;
CWinThread* pThread = AfxBeginThread (ThreadFunc, NULL, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); HANDLE hThread; ::DuplicateHandle (GetCurrentProcess (), pThread->m_hThread, GetCurrentProcess (), &hThread, 0, FALSE, DUPLICATE_SAME_ACCESS); pThread->ResumeThread (); // Sometime later DWORD dwExitCode; ::GetExitCodeThread (hThread, &dwExitCode); if (dwExitCode == STILL_ACTIVE) { // The thread is still running. } else { // The thread has terminated. Close the thread handle. ::CloseHandle (hThread); }
5.Terminating Another Thread
// Thread A
nContinue = 1;
CWinThread* pThread = AfxBeginThread (ThreadFunc, &nContinue);
HANDLE hThread = pThread->m_hThread; // Save the thread handle.
nContinue = 0; // Tell thread B to terminate.
::WaitForSingleObject (hThread, INFINITE);
//::WaitForSingleObject is an indispensable function that you'll use time and time again when writing multithreaded code
// Thread B
UINT ThreadFunc (LPVOID pParam)
{
int* pContinue = (int*) pParam;
while (*pContinue) {
// Work work work work
}
return 0;
}
Given a thread handle or a valid CWinThread object wrapping a thread handle, you can quickly determine whether the thread is still running by calling ::WaitForSingleObject and specifying 0 for the time-out period, as shown here:
if (::WaitForSingleObject (hThread, 0) == WAIT_OBJECT_0) {
// The thread no longer exists.
}
else {
// The thread is still running.
}
|
Called this way, ::WaitForSingleObject doesn't wait; it returns immediately. A return value equal to WAIT_OBJECT_0 means that the thread is signaled (no longer exists), and a return value equal to WAIT_TIMEOUT means that the thread is nonsignaled (still exists). As usual, it's up to you to ensure that the handle you pass to ::WaitForSingleObject is a valid one, either by duplicating the original thread handle or by preventing the CWinThread object from being autodeleted.
::TerminateThread (hThread, 0);