首先,我想應該先了解一下什麼是線程,操作系統裏說線程是系統可以管理的最小的單元,線程管理裏--操作系統控制着他的CPU使用;而我們拋開系統的概念,線程又是什麼呢?線程是一系列可以獨立執行的指令的堆棧,我們自己控制着代碼的執行,這就是爲什麼線程函數裏都要有一個循環的原因,只不過爲了更好的利用硬件的資源,我們引入了系統的概念,而多線程就是多套相互獨立的指令堆棧,如果沒有系統的管理線程的代碼也是可以單獨執行的,系統的最重要的工作是保護好線程堆棧的現場。
面向對象的方法讓我們很好的管理資源,所有設計到系統內核的資源,我們都有可能忘掉還給系統的時候,這時候就會出現系統資源的浪費,自從OO方法的出現就引入了利用對象來管理資源的方法,微軟在MFC已經採用了這樣的方法,但微軟的方法太臃腫(個人認爲i),在.NET平臺推出以後更是這樣;在LINIUX上也有很多這樣的類庫的代碼。
下面是我個人寫的一個類庫,利用這個庫可以很好的管理線程資源。
/************************************************************************
* 版權所有 (C)2008, 陳彥旭。
*
* 文件名稱: MyThread.h
* 內容摘要: 線程資源管理和使用
* 其它說明:
* 當前版本: 1.0.0.0
* 作 者: 陳彥旭
* 完成日期: 2008年01月20日
************************************************************************/
#if !defined(AFX_MYTHREAD_H__D97FB306_0742_43F7_8574_581DB0FBE538__INCLUDED_)
#define AFX_MYTHREAD_H__D97FB306_0742_43F7_8574_581DB0FBE538__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//#include <Thread.h>
#include <process.h>
#include "MyMutex.h"
class CMyThread
{
public:
CMyThread();
virtual ~CMyThread();
public:
static DWORD WINAPI ThreadFunc(LPVOID pParam);
public:
virtual BOOL AfterWork();
virtual BOOL Work();
virtual BOOL BeforeWork();
public:
BOOL IsRun();
BOOL IsPause();
BOOL IsSuspend();
BOOL IsExit();
BOOL SetExitState( BOOL bState );
BOOL SetRunState( BOOL bState );
BOOL SetPauseState( BOOL bState );
BOOL SetSuspendState( BOOL bState );
public:
BOOL RunThread();
BOOL StopThread( DWORD dwDelayTime=2000 );
BOOL SuspendThread();
BOOL ResumeThread();
void SetThreadName(CString sThreadName=_T(""));
CString GetThreadName();
HANDLE GetThreadHandle();
DWORD GetThreadID();
BOOL CloseThread();
private:
BOOL m_bRun;
BOOL m_bPause;
BOOL m_bExit;
BOOL m_bSuspend;
CString m_sThreadName;
CMyMutex m_RunMutex;
CMyMutex m_PauseMutex;
CMyMutex m_ExitMutex;
CMyMutex m_SuspendMutex;
HANDLE m_hThread;
DWORD m_dwThreadId;
};
#endif // !defined(AFX_MYTHREAD_H__D97FB306_0742_43F7_8574_581DB0FBE538__INCLUDED_)
// MyThread.cpp: implementation of the CMyThread class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyThread.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
typedef unsigned (__stdcall *PTHREAD_START) (void *);
#define chBEGINTHREADEX(psa, cbStack, pfnStartAddr, /
pvParam, fdwCreate, pdwThreadID) /
((HANDLE) _beginthreadex( /
(void *) (psa), /
(unsigned) (cbStack), /
(PTHREAD_START) (pfnStartAddr), /
(void *) (pvParam), /
(unsigned) (fdwCreate), /
(unsigned *) (pdwThreadID)))
CMyThread::CMyThread()
{
m_bRun = FALSE;
m_bPause = FALSE;
m_bExit = FALSE;
m_bSuspend = FALSE;
m_sThreadName = _T("");
m_hThread = NULL;
m_dwThreadId = 0;
}
CMyThread::~CMyThread()
{
}
BOOL CMyThread::AfterWork()
{
return TRUE;
}
BOOL CMyThread::Work()
{
return TRUE;
}
BOOL CMyThread::BeforeWork()
{
return TRUE;
}
BOOL CMyThread::IsRun()
{
CUseMutex mutex(&this->m_RunMutex);
return this->m_bRun;
}
BOOL CMyThread::IsPause()
{
CUseMutex mutex(&this->m_PauseMutex);
return this->m_bPause;
}
BOOL CMyThread::IsSuspend()
{
CUseMutex mutex(&this->m_SuspendMutex);
return this->m_bSuspend;
}
BOOL CMyThread::IsExit()
{
CUseMutex mutex(&this->m_ExitMutex);
return this->m_bExit;
}
BOOL CMyThread::SetExitState( BOOL bState )
{
CUseMutex mutex(&this->m_ExitMutex);
this->m_bExit = bState;
return TRUE;
}
BOOL CMyThread::SetRunState( BOOL bState )
{
CUseMutex mutex(&this->m_RunMutex);
this->m_bRun = bState;
return TRUE;
}
BOOL CMyThread::SetPauseState( BOOL bState )
{
CUseMutex mutex(&this->m_PauseMutex);
this->m_bPause = bState;
return TRUE;
}
BOOL CMyThread::SetSuspendState( BOOL bState )
{
CUseMutex mutex(&this->m_SuspendMutex);
this->m_bSuspend = bState;
return TRUE;
}
BOOL CMyThread::RunThread()
{
if (IsRun())
return TRUE;
this->SetExitState(FALSE);
this->SetPauseState(FALSE);
this->SetSuspendState(FALSE);
this->m_hThread = chBEGINTHREADEX( NULL, 0, CMyThread::ThreadFunc, (void*)this, 0, &this->m_dwThreadId);
if (NULL == this->m_hThread)
{
WQFTRACE("%s線程創建失敗errorno=%d /n", this->m_sThreadName, ::GetLastError());
return FALSE;
}
this->SetRunState(TRUE);
return TRUE;
}
DWORD WINAPI CMyThread::ThreadFunc(LPVOID pParam)
{
CMyThread* pThread = (CMyThread*)pParam;
if (!pThread->m_hThread)
{
WQFTRACE("%s線程句柄已失效! /n", pThread->m_sThreadName);
pThread->AfterWork();
pThread->SetRunState(FALSE);
return 0;
}
if (!pThread->BeforeWork())
{
pThread->SetRunState(FALSE);
pThread->AfterWork();
return 0;
}
while (!pThread->IsExit())
{
if (pThread->IsPause())
{
Sleep(1);
}
else
{
if (!pThread->Work())
break;
}
}
pThread->AfterWork();
pThread->SetRunState(FALSE);
return 0;
}
BOOL CMyThread::StopThread( DWORD dwDelayTime )
{
this->SetExitState(FALSE);
DWORD dwTime = ::timeGetTime();
while ((::timeGetTime()-dwTime) < dwDelayTime)
{
if (!this->IsRun())
{
return TRUE;
}
Sleep(10);
}
if (this->m_hThread)
{
static DWORD g_ThreadTerminateCount=0;
if (::TerminateThread(this->m_hThread, ++g_ThreadTerminateCount))
{
WQFTRACE("**********強制退出%s線程! /n", this->m_sThreadName);
WQFASSERT(FALSE);
}
}
this->CloseThread();
return TRUE;
}
BOOL CMyThread::SuspendThread()
{
return TRUE;
}
BOOL CMyThread::ResumeThread()
{
return TRUE;
}
void CMyThread::SetThreadName(CString sThreadName)
{
}
CString CMyThread::GetThreadName()
{
return this->m_sThreadName;
}
HANDLE CMyThread::GetThreadHandle()
{
return this->m_hThread;
}
DWORD CMyThread::GetThreadID()
{
return this->m_dwThreadId;
}
BOOL CMyThread::CloseThread()
{
if (this->m_hThread)
{
::CloseHandle(this->m_hThread);
this->m_hThread = NULL;
this->m_dwThreadId = 0;
}
return TRUE;
}
/************************************************************************
* 版權所有 (C)2008, 陳彥旭。
*
* 文件名稱: MyProcess.h
* 內容摘要: 線程資源管理和使用
* 其它說明:
* 當前版本: 1.0.0.0
* 作 者: 陳彥旭
* 完成日期: 2008年01月20日
************************************************************************/
#if !defined(AFX_MYPROCESS_H__F958678E_5978_421D_BE7E_56D6266DE6FB__INCLUDED_)
#define AFX_MYPROCESS_H__F958678E_5978_421D_BE7E_56D6266DE6FB__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
typedef BOOL (*ProcessCallback)(LPVOID lpUser, DWORD dwCommand, LPVOID lpData);
#include "MyThread.h"
typedef enum {
PROCESS_COMMAND_BEFORE,
PROCESS_COMMAND_PROCESS,
PROCESS_COMMAND_AFTER,
PROCESS_COMMAND_DELETE,
} process_command_t;
class CMyProcess : public CMyThread
{
public:
CMyProcess();
virtual ~CMyProcess();
private:
LPVOID m_lpUser;
ProcessCallback m_pCallback;
public:
void SetCallback(LPVOID lpUser, ProcessCallback callback);
virtual void DeleteData(void *pData);
BOOL Init();
BOOL ReInit();
BOOL UnInit();
private:
BOOL Work();
BOOL BeforeWork();
BOOL AfterWork();
BOOL Process(void *pData);
};
#endif // !defined(AFX_MYPROCESS_H__F958678E_5978_421D_BE7E_56D6266DE6FB__INCLUDED_)
// MyProcess.cpp: implementation of the CMyProcess class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyProcess.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMyProcess::CMyProcess()
{
this->m_lpUser = NULL;
this->m_pCallback = NULL;
}
CMyProcess::~CMyProcess()
{
this->UnInit();
}
void CMyProcess::SetCallback(LPVOID lpUser, ProcessCallback callback)
{
this->m_lpUser = lpUser;
this->m_pCallback = callback;
}
void CMyProcess::DeleteData(void *pData)
{
this->m_pCallback(this->m_lpUser, PROCESS_COMMAND_DELETE, pData);
}
BOOL CMyProcess::Work(void)
{
return this->Process(NULL);
}
BOOL CMyProcess::BeforeWork()
{
return this->m_pCallback(this->m_lpUser, PROCESS_COMMAND_BEFORE, NULL);
}
BOOL CMyProcess::AfterWork()
{
return this->m_pCallback(this->m_lpUser, PROCESS_COMMAND_AFTER, NULL);
}
BOOL CMyProcess::Init()
{
return TRUE;
}
BOOL CMyProcess::ReInit()
{
return TRUE;
}
BOOL CMyProcess::UnInit()
{
return TRUE;
}
BOOL CMyProcess::Process(void* pData)
{
return this->m_pCallback(this->m_lpUser, PROCESS_COMMAND_PROCESS, pData);
}
/************************************************************************
* 版權所有 (C)2008, 陳彥旭。
*
* 文件名稱: MyMutex.h
* 內容摘要: 互斥資源管理和使用
* 其它說明:
* 當前版本: 1.0.0.0
* 作 者: 陳彥旭
* 完成日期: 2008年01月20日
************************************************************************/
#if !defined(AFX_MYMUTEX_H__A0C8824F_B61A_443B_83DA_7F73FC0FD481__INCLUDED_)
#define AFX_MYMUTEX_H__A0C8824F_B61A_443B_83DA_7F73FC0FD481__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CMyMutex
{
public:
CMyMutex();
virtual ~CMyMutex();
public:
BOOL Lock(DWORD dwLockTime=INFINITE);
void Unlock();
BOOL TryLock();
private:
CRITICAL_SECTION m_Mutex;
};
class CUseMutex
{
public:
CUseMutex();
CUseMutex(CMyMutex* plock, BOOL bLock=TRUE, DWORD dwLockTime=INFINITE);
virtual ~CUseMutex();
public:
BOOL IsUseLock();
BOOL UseLock(DWORD dwLockTime=INFINITE);
BOOL UseLock(CMyMutex* plock, BOOL bLock, DWORD dwLockTime=INFINITE);
void UseUnlock();
private:
BOOL m_bLock;
CMyMutex* m_pLock;
};
#endif // !defined(AFX_MYMUTEX_H__A0C8824F_B61A_443B_83DA_7F73FC0FD481__INCLUDED_)
// MyMutex.cpp: implementation of the CMyMutex class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyMutex.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMyMutex::CMyMutex()
{
::InitializeCriticalSection(&this->m_Mutex);
}
CMyMutex::~CMyMutex()
{
::DeleteCriticalSection(&this->m_Mutex);
}
BOOL CMyMutex::Lock(DWORD dwLockTime)
{
::EnterCriticalSection(&this->m_Mutex);
return TRUE;
}
void CMyMutex::Unlock()
{
::LeaveCriticalSection(&this->m_Mutex);
}
BOOL CMyMutex::TryLock()
{
#if(_WIN32_WINNT >= 0x0400)
::TryEnterCriticalSection(&this->m_Mutex);
#else
::EnterCriticalSection(&this->m_Mutex);
#endif
return FALSE;
}
CUseMutex::CUseMutex()
{
this->m_pLock = NULL;
this->m_bLock = FALSE;
}
CUseMutex::CUseMutex(CMyMutex* plock, BOOL bLock, DWORD dwLockTime)
{
this->m_pLock = plock;
this->m_bLock = FALSE;
if (this->m_pLock && bLock)
{
this->m_bLock = this->m_pLock->Lock(dwLockTime);
}
}
CUseMutex::~CUseMutex()
{
this->UseUnlock();
}
BOOL CUseMutex::IsUseLock()
{
return (this->m_pLock && this->m_bLock);
}
BOOL CUseMutex::UseLock(DWORD dwLockTime)
{
if (this->m_pLock && !this->m_bLock)
this->m_bLock = this->m_pLock->Lock(dwLockTime);
return this->m_bLock;
}
BOOL CUseMutex::UseLock(CMyMutex* plock, BOOL bLock, DWORD dwLockTime)
{
this->UseUnlock();
this->m_pLock = plock;
this->m_bLock = FALSE;
if (this->m_pLock && bLock)
return this->m_bLock = this->m_pLock->Lock(dwLockTime);
return FALSE;
}
void CUseMutex::UseUnlock()
{
if (this->IsUseLock())
this->m_pLock->Unlock();
this->m_bLock = FALSE;
}