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

向我老大致敬!

 

这个做法其实是抄我老大的。服务器中,多线程经常需要使用临界区,为了简化代码的使用,把临界区封装为 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    不错的线程同步文章

posted @ 2014-09-02 14:29  不笑猫  阅读(2211)  评论(0编辑  收藏  举报