临界区(Critical Section)的封装和使用示例

16 篇文章 0 订阅
2 篇文章 0 订阅
转自
[url]http://www.cnblogs.com/sixbeauty/p/3951406.html[/url]

这个做法其实是抄我老大的。服务器中,多线程经常需要使用临界区,为了简化代码的使用,把临界区封装为 CThreadLockHandle 类,通过封装,使用临界区资源每次只需要一行代码,而且只要确定对象的生存周期,就能完成对临界区资源的自动释放:

头文件:

//thread_lock.h
#ifndef THREAD_LOCK_HEAD_FILE
#define THREAD_LOCK_HEAD_FILE
#include<windows.h>


//临界区同步类
class CThreadLock
{
//变量定义
private:
CRITICAL_SECTION m_csLock; //临界区变量

//函数定义
public:
//构造函数
inline CThreadLock() { ::InitializeCriticalSection(&m_csLock); };
//析构函数
inline ~CThreadLock() { ::DeleteCriticalSection(&m_csLock); };

//功能函数
public:
//锁定函数
inline void Lock() { ::EnterCriticalSection(&m_csLock); };
//解锁函数
inline void UnLock() { ::LeaveCriticalSection(&m_csLock); };
};



//安全同步锁定句柄
class CThreadLockHandle
{
//变量定义
private:
int m_nLockCount; //锁定计数
CThreadLock *m_pThreadLock; //锁定对象

//函数定义
public:
//构造函数
CThreadLockHandle(CThreadLock *pThreadLock, bool bAutoLock=true);
//析构函数
virtual ~CThreadLockHandle();

//功能函数
public:
//锁定函数
void Lock();
//解锁函数
void UnLock();
//火枪锁定次数
int inline GetLockCount() { return m_nLockCount; };
};

#endif


源文件:

//thread_lock.cpp programed by sany
//2014.9.2
//callme:sanyue9394@163.com


#include "thread_lock.h"
#include<assert.h>


//安全同步锁定句柄
//构造函数
CThreadLockHandle::CThreadLockHandle(CThreadLock *pThreadLock, bool bAutoLock)
{
assert(pThreadLock!=NULL);
m_nLockCount=0;
m_pThreadLock=pThreadLock;
if(bAutoLock) Lock();
return;
}
//析构函数
CThreadLockHandle::~CThreadLockHandle()
{
while(m_nLockCount>0) UnLock(); //生存周期结束自动解锁
}

//锁定函数
void CThreadLockHandle::Lock()
{
//校验状态
assert(m_nLockCount>=0);
assert(m_pThreadLock!=NULL);

//锁定对象
m_nLockCount++;
m_pThreadLock->Lock();
}

//解锁函数
void CThreadLockHandle::UnLock()
{
//校验状态
assert(m_nLockCount>0);
assert(m_pThreadLock!=NULL);

//解除状态
m_nLockCount--;
m_pThreadLock->UnLock();
}


经过这个类的封装,使用临界区实现线程同步只需要2步:

1.初始化一个全局的 CThreadLock 对象,为后面调用做准备。

2.每当需要使用临界区时,在作用域中声明一个局部变量:CThreadLockHandle ,当其生存周期结束时,将自动释放临界区资源


使用例子:

#include<stdio.h>
#include<windows.h>
#include <process.h>
#include"thread_lock.h"

const int aSize=10;
char szArr[aSize+1]={};

CThreadLock threadLock; //声明CThreadLock类型的全局变量

unsigned _stdcall threadFunc1(void*)
{
CThreadLockHandle lockHandle(&threadLock); //需要使用临界区是,声明一个CThreadLockHandle类型的变量,其生存周期结束自动解锁
for(int s=0;s<aSize;s++)
{
szArr[s]='a';
Sleep(1);
}
return 0;
}

unsigned _stdcall threadFunc2(void*)
{
CThreadLockHandle lockHandle(&threadLock); //需要使用临界区是,声明一个CThreadLockHandle类型的变量,其生存周期结束自动解锁
for(int s=0;s<aSize;s++)
{
szArr[aSize-1-s]='b';
Sleep(1);
}
return 0;
}

int main()
{
memset(szArr,0,sizeof(szArr));
HANDLE handle1=(HANDLE)_beginthreadex(NULL,0,threadFunc1,NULL,0,0);
HANDLE handle2=(HANDLE)_beginthreadex(NULL,0,threadFunc2,NULL,0,0);

WaitForSingleObject(handle1,INFINITE);
WaitForSingleObject(handle2,INFINITE);

printf("%s\n",szArr);
CloseHandle(handle1);
CloseHandle(handle2);

return 0;
}


如果在类中调用,把CThreadLock 对象声明为私有或保护成员即可:

class threadtest
{
protected:
static CThreadLock m_ThreadLock; //线程锁

public:
static unsigned _stdcall threadFunction(void* pThreadData);
};
unsigned _stdcall threadtest::threadFunction(void* pThreadData)
{
CThreadLockHandle lockHandle(&m_ThreadLock); //生存周期结束自动解锁
//doSomething
return 0;
}



附:http://www.cnblogs.com/userinterface/archive/2005/04/27/146137.html 不错的线程同步文章
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值