//小弟是新手,最近在学WIN API ,写了个同步对象,请各位大虾多多指教阿
///
//CSynchonize.h
//
#pragma once
#define _WIN32_WINNT 0x04000
#include <Windows.h>
#include <tchar.h>
class CSynchonize
{
public:
//构造函数,确定循环锁的循环次数,默认是0
CSynchonize(DWORD dwSpinCount=2000);
virtual ~CSynchonize(void);
//尝试得到资源的访问权,成功则返回TRUE,否则返回FALSE
virtual BOOL TryEnter(void);
//要求得到资源的访问权,得不到则让线程等待
virtual void Enter(void);
//放弃资源的访问权
virtual void Leave(void);
#ifdef _Wp64
//如果是是64位程序则返回64位值
DWORD64 GetObjectID();
#else
//如果是是32位程序则返回32位值
DWORD32 GetObjectID();
#endif
protected:
//循环锁的循环次数
volatile DWORD m_dwSpinCount;
//目前拥有当前拥有该对像的线程的ID
volatile DWORD m_dwThreadID;
//事件内核对象的句柄
HANDLE m_hEvent;
// 正在等待该对象的线程的个数
DWORD m_dwWaitNum;
// 对象是否被某个线程所占有
volatile BOOL m_bIsOwn;
};
/
//CSynchonize..cpp
/
#include "CSynchonize.h"
CSynchonize::CSynchonize(DWORD dwSpinCount)
: m_dwSpinCount(dwSpinCount)
, m_dwThreadID(0)
, m_hEvent(NULL)
, m_dwWaitNum(0)
, m_bIsOwn(FALSE)
{
//取得本机上的CPU个数
SYSTEM_INFO si;
GetSystemInfo(&si);
//如果CPU只有一个,则循环锁没有意义,循环锁计数置0
if(si.dwNumberOfProcessors==1)
m_dwSpinCount=0;
//创建一个无名的事件内核对象
m_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
}
CSynchonize::~CSynchonize(void)
{
//关闭事件内核对象的句柄
CloseHandle(m_hEvent);
}
BOOL CSynchonize::TryEnter(void)
{
//取得当前线程的ID
DWORD dwCurrentThreadID=::GetCurrentThreadId();
//取得当前线程的真句柄
//如果线程已经拥有这个对象,则直接返回TRUE
if(dwCurrentThreadID==m_dwThreadID&&InterlockedCompareExchange((LONG*)&m_bIsOwn,TRUE,TRUE))
return TRUE;
//循环锁,尝试获得对象的拥有权
//如果循坏锁成功则返回TRUE
DWORD dwSpinCount=m_dwSpinCount;
do{
//获得线程的拥有权
if (FALSE==InterlockedCompareExchange((LONG*)&m_bIsOwn,TRUE,FALSE))
{
//记录当前线程的ID
InterlockedExchange((LONG*)&m_dwThreadID,dwCurrentThreadID);
//循环锁成功,返回TRUE
return TRUE;
}
}while(dwSpinCount-->0);
//循环锁失败,返回FALSE
return FALSE;
}
void CSynchonize::Enter(void)
{
//如果循环锁尝试成功则返回
if (TRUE==TryEnter())
return;
//循环锁尝试失败,则取得取得当前线程的ID和句柄,并等待拥有该对象的线程
//取得当前线程的ID和句柄
DWORD dwCurrentThreadID=GetCurrentThreadId();
//递增等待该对象的线程的计数
InterlockedIncrement((LONG*)&m_dwWaitNum);
//等待事件内核对象的触发
WaitForSingleObject(m_hEvent,INFINITE);
//获得对象的拥有权
InterlockedExchange((LONG*)&m_bIsOwn,TRUE);
//记录当前线程的ID
InterlockedExchange((LONG*)&m_dwThreadID,dwCurrentThreadID);
//递减等待该对象的线程的计数
InterlockedDecrement((LONG*)&m_dwWaitNum);
}
void CSynchonize::Leave(void)
{
//将当前的线程ID改为0
DWORD dwThreadID=GetCurrentThreadId();
if(InterlockedCompareExchange((LONG*)&m_dwThreadID,0,dwThreadID)!=dwThreadID)
return;
if(0!=m_dwWaitNum)
{
//将事件内核对象置为触发状态,然后置为非触发
SetEvent(m_hEvent);
}
//放弃对对象的拥有权
InterlockedCompareExchange((LONG*)&m_bIsOwn,TRUE,FALSE);
}
#ifdef _Wp64
//如果是是64位程序则返回64位值
DWORD64 CSynchonize::GetObjectID(void)
{
return (DWORD64)this;
}
#else
//如果是是32位程序则返回32位值
DWORD32 CSynchonize::GetObjectID(void)
{
return (DWORD32)this;
}
#endif