这篇文章有参考ue5源码和其他源码。
多线程同步.h文件
/**
* 关键段 用户模式下同步对象,除非竞争非常激烈,否则不会进入内核模式
*/
class SYSTEM_API MCriticalSection
{
#if WINDOWS_PLATFORM //平台宏
CRITICAL_SECTION m_CriticalSection;
#endif
public:
inline MCriticalSection(void)
{
#ifdef WINDOWS_PLATFORM
//使用前必须被初始化,如果未初始化CRITICAL_SECTION将不可预料
InitializeCriticalSection(&m_CriticalSection);
//设置自旋锁,循环4000次
SetCriticalSectionSpinCount(&m_CriticalSection, 4000);
#endif
}
inline ~MCriticalSection()
{
#ifdef WINDOWS_PLATFORM
//会重置结构中的成员变量
DeleteCriticalSection(&m_CriticalSection);
#endif
}
inline void Lock(void)
{
#ifdef WINDOWS_PLATFORM
//以原子的方式检查结构中的成员变量,这些变量表示是否有线程在访问资源已经哪个线程在访问资源
EnterCriticalSection(&m_CriticalSection);
#endif
}
inline bool TryLock()
{
//不让调用线程等待,返回是否允许访问资源
return TryEnterCriticalSection(&m_CriticalSection);
}
inline void Unlock(void)
{
#ifdef WINDOWS_PLATFORM
//检查结构内存的成员变量同时将获准访问共享资源的计数减一,如果计数器大于0则直接返回,等于0 更新成员变量,表示没有任何线程在访问被保护的资源
LeaveCriticalSection(&m_CriticalSection);
#endif
}
class Locker
{
public:
Locker(MCriticalSection& inCriticalSection)
:in_criticalSection(inCriticalSection)
{
in_criticalSection.Lock();
}
~Locker()
{
in_criticalSection.Unlock();
}
private:
MCriticalSection& in_criticalSection;
};
};
多线程.h文件
#pragma once
#include "MSynchronize.h"
namespace Unknown
{
enum Priority :UINT8
{
Low = 20u,
Normal,
High,
};
enum ThreadState :UINT8
{
TS_START,
TS_SUSPEND,
TS_STOP,
};
class SYSTEM_API MThread
{
public:
MThread();
virtual ~MThread();
void SetPriority(Priority p);
Priority GetPriority() const;
void SetStackSize(unsigned int uiSize);
unsigned int GetStackSize() const;
void Start();
void Suspend();
bool IsRunning() const;
static void Sleep(DWORD dwMillseconds);
bool IsStopTrigger();
void Stop();
public:
static void SetThreadName(const TCHAR* name, const UINT32 id);
inline ThreadState GetThreadState()
{
return m_ThreadState;
}
protected:
virtual void Run() = 0;
virtual const TCHAR* GetThreadName();
private:
static DWORD THREAD_CALLBACK ThreadProc(void* t);//宏 __stdcall
private:
void* m_hThread;
Priority m_priority;
unsigned int m_stackSize;
protected:
ThreadState m_ThreadState;
MEvent m_StopEvent;
UINT32 ui_ThreadID;
};
}
多线程.cpp
#include "MThread.h"
#include <process.h>
using namespace Unknown;
MThread::MThread():m_hThread(nullptr),m_priority(Normal),m_stackSize(0)
{
MAC_ASSERT(!IsRunning());
#if WINDOWS_PLATFORM
//_beginthreadex();
m_hThread = ::CreateThread(0, m_stackSize, ThreadProc, this, CREATE_SUSPENDED, NULL);
#else
static_assert(0, "no thread implement");
#endif
MAC_ASSERT(m_hThread);
m_ThreadState = TS_SUSPEND;
SetPriority(m_priority);
m_StopEvent.Create(true);
m_StopEvent.Reset();
}
MThread::~MThread()
{
if (IsRunning())
{
#if WINDOWS_PLATFORM
WaitForSingleObjectEx(m_hThread, INFINITE, FALSE);
// force to exit
TerminateThread(m_hThread, 0);
#else
static_assert(0, "no thread implement");
#endif
}
if (m_hThread)
{
#if WINDOWS_PLATFORM
CloseHandle(m_hThread);
#else
static_assert(0, "no thread implement");
#endif
}
m_hThread = nullptr;
}
void MThread::SetPriority(Priority p)
{
int nPriority = THREAD_PRIORITY_NORMAL;
if (p == Low)
nPriority = THREAD_PRIORITY_BELOW_NORMAL;
else if (p == Normal)
nPriority = THREAD_PRIORITY_NORMAL;
else if (p == High)
nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
#if WINDOWS_PLATFORM
::SetThreadPriority(m_hThread, nPriority);
#else
static_assert(0, "no thread implement");
#endif
}
Priority MThread::GetPriority() const
{
return m_priority;
}
void MThread::Start()
{
if (m_ThreadState == TS_SUSPEND)
{
#if WINDOWS_PLATFORM
ResumeThread((HANDLE)m_hThread);
#else
static_assert(0, "no thread implement");
#endif
m_ThreadState = TS_START;
}
}
void MThread::Suspend()
{
if (m_ThreadState == TS_START)
{
#if WINDOWS_PLATFORM
SuspendThread((HANDLE)m_hThread);
#else
static_assert(0, "no thread implement");
#endif
m_ThreadState = TS_SUSPEND;
}
}
bool MThread::IsRunning() const
{
if (NULL != m_hThread)
{
#if WINDOWS_PLATFORM
DWORD exitCode = 0;
if (GetExitCodeThread(m_hThread, &exitCode))
{
if (STILL_ACTIVE == exitCode)
{
return true;
}
}
#else
static_assert(0, "no thread implement");
#endif
}
return false;
}
void MThread::Sleep(DWORD dwMillseconds)
{
#if WINDOWS_PLATFORM
::Sleep(dwMillseconds);
#else
static_assert(0, "no thread implement");
#endif
}
bool MThread::IsStopTrigger()
{
return m_StopEvent.IsTrigger();
}
void MThread::Stop()
{
if (m_ThreadState == TS_START)
{
MAC_ASSERT(this->IsRunning());
MAC_ASSERT(NULL != m_hThread);
m_StopEvent.Trigger();
m_ThreadState = TS_STOP;
#if WINDOWS_PLATFORM
// 进入等待状态,等待线程终止
WaitForSingleObject(m_hThread, INFINITE);
//WaitForSingleObjectEx(m_hThread, INFINITE, false);
CloseHandle(m_hThread);
#else
static_assert(0, "no thread implement");
#endif
m_hThread = NULL;
}
}
void MThread::SetThreadName(const TCHAR* name,const UINT32 id)
{
#if WINDOWS_PLATFORM
const UINT32 MS_VC_EXCEPTION = 0x406D1388;
//更新线程名,使其正确的显示在调试器
struct THREADNAME_INFO
{
DWORD dwType; // 必须是0x1000
TCHAR szName; //线程名
UINT32 dwThreadID; // 线程id
DWORD dwFlags; // 保留以供将来使用,必须为零
};
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = *name;
info.dwThreadID = id;
info.dwFlags = 0;
__try
{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
#else
static_assert(0, "no thread implement");
#endif
}
const TCHAR* MThread::GetThreadName()
{
return _T("Thread");
}
DWORD THREAD_CALLBACK MThread::ThreadProc(void* t)
{
MThread* pThread = (MThread*)(t);
SetThreadName(pThread->GetThreadName(),::GetCurrentThreadId());
pThread->Run();
return 0;
}
标签:WINDOWS,void,实践,PLATFORM,endif,MThread,多线程,hThread
From: https://www.cnblogs.com/zjr0/p/16996063.html