?? threadbas.h
字號:
#if !defined(CCL_THREADBAS_H_001064A8_932C_40ca_B559_7356BB029D6A_INCLUDED_)
#define CCL_THREADBAS_H_001064A8_932C_40ca_B559_7356BB029D6A_INCLUDED_
#include <windows.h>
/////////////////////////////////////////////////////////////////////////////
// //
// -->-> class CThreadBase <-<-- //
// //
// Win32線程基類,在需要一個后臺Win32線程的場合,從CThreadBase派生一個 //
// 類,并在派生類中重載ThreadProc和MessageProc函數,即可利用該派生類控制和 //
// 使用一個后臺Win32線程。 //
// CThreadBase的直接派生類(即派生類沒有增加新的成員函數)對象可以被多 //
// 線程并發訪問。 //
// //
/////////////////////////////////////////////////////////////////////////////
class CThreadBase
{
protected:
CThreadBase()
{
m_dwThreadID=0;
m_hThread=NULL;
m_bRuning=FALSE;
m_hMutex=::CreateMutex(NULL,FALSE,NULL);
}
virtual ~CThreadBase()
{
ActiveThread(FALSE);
if(m_hMutex!=NULL)
::CloseHandle(m_hMutex);
}
public:
//激活/終止線程
//<參數>
// bActive: 為TRUE表示激活線程,為FALSE表示終止線程
//<返回值>
// 如果成功返回TRUE,否則返回FALSE。
BOOL ActiveThread(/*[in]*/BOOL bActive=TRUE)
{
//對象被其他線程長時間鎖定將導致調用失敗
BOOL bRet=TRUE;
if(bActive)
{
LockAccess();
//如果m_bRuning==TRUE表示線程已經被激活
if(m_bRuning==FALSE)
{
m_bRuning=TRUE; //m_bRuning=TRUE將使得后臺線程持續運行
m_hThread=::CreateThread(NULL,0,CThreadBase::Thread,LPVOID(this),0,&m_dwThreadID);
if(m_hThread==NULL)
{
m_bRuning=FALSE;
bRet=FALSE;
} //if(m_hThread==NULL)
} //if(m_bRuning==FALSE)
UnlockAccess();
} //if(bActive)
else
{
LockAccess();
if(m_bRuning==TRUE)
{
//m_bRuning=FALSE將使線程終止運行
m_bRuning=FALSE;
UnlockAccess();
//等待線程終止
if(::WaitForSingleObject(m_hThread,5000)==WAIT_TIMEOUT)
{
//強行終止線程
::TerminateThread(m_hThread,0);
}
::CloseHandle(m_hThread);
m_hThread=NULL;
m_dwThreadID=0;
}
else
UnlockAccess();
} //if(bActive) else
return bRet;
}
//獲取對象線程的ID
//<參數> 無
//<返回值>
// 如果因為線程互斥導致訪問對象失敗或對象線程未激活返回0,否則返回對象線程的ID。
DWORD GetThreadID(void)
{
if(LockAccess()==FALSE)
return 0;
DWORD dwID=m_dwThreadID;
UnlockAccess();
return dwID;
}
//向對象線程拋送消息
//<參數>
// uiMsg: 消息值
// wParam: 消息附加參數
// lParam: 消息附加參數
//<返回值>
// 如果成功返回TRUE,否則返回FALSE。
BOOL PostThreadMessage(/*[in]*/UINT uiMsg,/*[in]*/WPARAM wParam,/*[in]*/LPARAM lParam)
{
if(LockAccess()==FALSE)
return FALSE;
BOOL bRet=FALSE;
if(m_dwThreadID)
bRet=::PostThreadMessage(m_dwThreadID,uiMsg,wParam,lParam);
UnlockAccess();
return bRet;
}
//設置對象線程的優先級
//<參數>
// iPriority:線程優先級
//<返回值>
// 如果成功返回TRUE,否則返回FALSE。
BOOL SetThreadPriority(/*[in]*/int iPriority=THREAD_PRIORITY_NORMAL)
{
if(LockAccess()==FALSE)
return FALSE;
BOOL bRet=FALSE;
if(m_hThread!=NULL)
bRet=::SetThreadPriority(m_hThread,iPriority);
UnlockAccess();
return bRet;
}
//判斷線程是否已經激活
//<參數> 無
//<返回值>
// 如果線程已經激活返回TRUE,否則返回FALSE。
BOOL IsActived(void)
{
LockAccess();
BOOL bIsActived=m_bRuning;
UnlockAccess();
return bIsActived;
}
protected:
//線程處理函數,被對象線程不斷調用直到對象線程終止。
//該函數如果返回FALSE,將使對象線程終止。
//派生類通過重載該函數進入對象線程
virtual BOOL ThreadProc(void){return TRUE;};
//線程消息處理函數,對象線程在收到線程消息時調用該函數。
//該函數如果返回FALSE,將使對象線程終止。
//<參數>
// rMsg:對象線程收到的消息。
virtual BOOL MessageProc(/*[in]*/MSG &rMsg){return TRUE;};
//該函數在線程創建成功后被線程調用如果其返回FALSE,新線程將立即終止。
//新線程在退出前將調用OnThreadDestroy。
virtual BOOL OnThreadCreate(void){return TRUE;}
//該函數在線程退出前被線程調用,其返回值將被作為線程的終止代碼。
//<參數>
// ulExitCode:線程準備的終止代碼
virtual ULONG OnThreadDestroy(/*[in]*/ULONG ulExitCode){return ulExitCode;}
protected:
//鎖定對象的訪問,防止多線程訪問沖突
//<參數>
// dwWait: 線程互斥等待時間,單位是ms
//<返回值>
// 如果成功成功鎖定鏈表則返回TRUE,否則返回FALSE。
BOOL LockAccess(/*[in]*/DWORD dwWait=500)
{
if(m_hMutex==NULL)
return TRUE;
if(::WaitForSingleObject(m_hMutex,dwWait)==WAIT_TIMEOUT)
return FALSE;
return TRUE;
}
//解除對鏈表的鎖定,允許其它線程訪問鏈表
void UnlockAccess(void)
{
if(m_hMutex)
::ReleaseMutex(m_hMutex);
}
private:
//對象線程ID
DWORD m_dwThreadID;
//對象線程句柄
HANDLE m_hThread;
//對象訪問互斥量
HANDLE m_hMutex;
//對象線程激活標志
BOOL m_bRuning;
//對象線程入口函數
static ULONG __stdcall Thread(/*[in]*/LPVOID lpParam);
};
//對象線程入口函數
//參見Win32sAPI手冊
inline ULONG __stdcall CThreadBase::Thread(/*[in]*/LPVOID lpParam)
{
if(lpParam==NULL)
return 0;
CThreadBase * p=(CThreadBase *)lpParam;
if(p->OnThreadCreate()==FALSE)
{
p->LockAccess();
p->m_bRuning=FALSE;
p->m_dwThreadID=0;
p->m_hThread=NULL;
p->UnlockAccess();
::ExitThread(p->OnThreadDestroy(0));
}
MSG stMsg;
//循環調用ThreadProc函數直到其返回FALSE或m_bRuning==FALSE,
//如果收到線程消息則調用MessageProc處理消息
while(p->m_bRuning==TRUE)
{
//如果收到線程消息...
if(::PeekMessage(&stMsg,HWND(-1),0,0,PM_REMOVE)==TRUE)
{
if(p->MessageProc(stMsg)==FALSE)
{
if(p->LockAccess()==FALSE)
continue;
p->m_bRuning=FALSE;
p->m_dwThreadID=0;
p->m_hThread=NULL;
p->UnlockAccess();
break;
}
}
if(p->ThreadProc()==FALSE)
{
if(p->LockAccess()==FALSE)
continue;
p->m_bRuning=FALSE;
p->m_dwThreadID=0;
p->m_hThread=NULL;
p->UnlockAccess();
break;
}
}
while(::PeekMessage(&stMsg,HWND(-1),0,0,PM_REMOVE));
::ExitThread(p->OnThreadDestroy(0));
return 0;
}
#endif // !defined(CCL_THREADBAS_H_001064A8_932C_40ca_B559_7356BB029D6A_INCLUDED_)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -