一个有用的线程例子:
Spinlock.h文件:
#pragma once
#include <stdio.h>
#include <windows.h>
#include <process.h>
#define AUTO_LOCK(x) \
CAutoLock lock(x);
class CSpinLock
{
public:
CSpinLock()
{
CSpinLock(0);
}
CSpinLock(unsigned long SpinCount) : m_nSpinCount(SpinCount)
{
memset(&m_sec, 0, sizeof(CRITICAL_SECTION));
}
void Lock()
{
EnterCriticalSection(&m_sec);
}
bool IsLock()
{
if (TryEnterCriticalSection(&m_sec) == 0) // owned by another thread
return false;
else
{
Unlock();
return true;
}
}
void Unlock()
{
LeaveCriticalSection(&m_sec);
}
bool TryLock()
{
return TryEnterCriticalSection(&m_sec) != 0 ? true : false;
}
void Init()
{
InitializeCriticalSectionAndSpinCount(&m_sec, m_nSpinCount);
}
void Term()
{
DeleteCriticalSection(&m_sec);
}
operator CRITICAL_SECTION&()
{
return m_sec;
}
private:
unsigned long m_nSpinCount;
CRITICAL_SECTION m_sec;
};
class CAutoSpinLock : public CSpinLock
{
public:
CAutoSpinLock() : CSpinLock(m_nSpinCount)
{
__super::Init();
}
~CAutoSpinLock()
{
__super::Term();
}
private:
void Init();
void Term();
private:
static const unsigned long m_nSpinCount = 1000;
};
class CAutoLock
{
public:
CAutoLock( CRITICAL_SECTION& cs )
{
m_pcs = &cs;
EnterCriticalSection( m_pcs );
}
~CAutoLock()
{
LeaveCriticalSection( m_pcs );
}
LPCRITICAL_SECTION m_pcs;
};
//simulator aouto loack for safe power switch
//when enter, power switch off
//when exit, power switch on
class CPowerSwitchAutoLock
{
public:
CPowerSwitchAutoLock( CRITICAL_SECTION& cs , bool& bSwitchOn)
{
m_pcs = &cs;
m_pSwitch = &bSwitchOn;
EnterCriticalSection( m_pcs );
*m_pSwitch = false;
}
~CPowerSwitchAutoLock()
{
LeaveCriticalSection( m_pcs );
*m_pSwitch = true;
}
private:
bool* m_pSwitch;
LPCRITICAL_SECTION m_pcs;
};
SimpleThread.h文件:
#pragma once
#include "Spinlock.h"
class CSimpleThread
{
public:
CSimpleThread(void) : m_hThread(NULL), m_hEventStop(NULL), m_iStopFlag(0), m_iStopped(1) {}
virtual ~CSimpleThread(void)
{
SyncStop();
if (m_hThread != NULL) // stopped
{
CloseHandle(m_hThread);
m_hThread = NULL;
}
}
bool Start()
{
CAutoLock gurd(m_lock);
if (IsRunning())
{
return true;
}
if (m_hThread != NULL) // stopped
{
CloseHandle(m_hThread);
m_hThread = NULL;
}
m_hEventStop = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hEventStop == NULL)
{
return false;
}
m_iStopFlag = 0;
m_hThread = (HANDLE)_beginthreadex(NULL, 0, &CSimpleThread::ThreadProc, this, 0, NULL);
if (m_hThread == NULL)
{
return false;
}
m_iStopped = 0;
return true;
}
void SyncStop()
{
AsyncStop();
// wait until thread exit
WaitForSingleObject(m_hThread, INFINITE);
}
void AsyncStop()
{
CAutoLock gurd(m_lock);
// already stopped
if (m_iStopped) { return; }
// notify stop
m_iStopFlag = 1;
SetEvent(m_hEventStop);
}
bool IsRunning() { return !m_iStopped ? true : false; }
protected:
/** end loop if stop flag set, */
virtual void Run(){ Sleep(0); };
bool IsScheduledToStop() {return m_iStopFlag ? true : false;}
void Wait(DWORD dwMilliseconds) { WaitForSingleObject(m_hEventStop, dwMilliseconds); }
private:
static unsigned __stdcall ThreadProc(void* lpData)
{
CSimpleThread* pThis = (CSimpleThread*)lpData;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
pThis->Run();
CoUninitialize();
CAutoLock gurd(pThis->m_lock);
CloseHandle(pThis->m_hEventStop);
pThis->m_hEventStop = NULL;
pThis->m_iStopFlag = 0;
pThis->m_iStopped = 1;
return S_OK;
}
CAutoSpinLock m_lock;
HANDLE m_hThread;
HANDLE m_hEventStop;
int m_iStopFlag;
int m_iStopped;
};
以上两个文件是基础类。
下面是测试类:
TestThread.h
//测试线程类
#pragma once
#include <iostream>
#include "SimpleThread.h"
using namespace std;
class CTestThread : public CSimpleThread
{
public:
CTestThread();
~CTestThread();
void Initialize();
void Terminate();
virtual void Run();
private:
int m_Tick;
};
TestThread.cpp
#include "stdafx.h"
#include "TestThread.h"
CTestThread::CTestThread() : m_Tick(1000)
{
}
CTestThread::~CTestThread()
{
}
void CTestThread::Initialize()
{
Start();
}
void CTestThread::Terminate()
{
AsyncStop();
}
void CTestThread::Run()
{
while (!IsScheduledToStop())
{
cout << "aaa" << endl;
Wait(m_Tick);
}
}
Main中测试调用:
int _tmain(int argc, _TCHAR* argv[])
{
CTestThread test;
test.Initialize();
Sleep(10 * 1000);
test.Terminate();
}