同步对象

//小弟是新手,最近在学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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值