📄 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 + -