巧用析构函数解锁

来源:互联网 发布:java private修饰类 编辑:程序博客网 时间:2024/06/05 06:30

             由于最近经常用到锁的操作,所以打算写一篇文章记录下相关的操作和感想。以下就用临界区(Window平台)举例子。 假如有个SetVal函数,该函数需要用到加锁和解锁,该函数有多个出口,第1版本的SetVal代码如下:

int SetVal(int iVal){    CRITICAL_SECTION stSection;    InitializeCriticalSection(&stSection);    EnterCriticalSection(&stSection);       if ( 1 == iVal )    {       g_iVal = 2;       LeaveCriticalSection(&stSection);       return 1;    }    else if( 2 == iVal)    {       g_iVal = 10;       LeaveCriticalSection(&stSection);       return 2;    }    else     {       g_iVal = 20;       LeaveCriticalSection(&stSection);    }     return 0; }

            假如写代码的时候不小心少写了解锁的代码,对后面的影响是很大的。是否有好的办法既减少编写代码错误,同时不必要每个函数出口点都添加解锁代码呢?想到当对象生命期结束时会自动调用其析构函数,如果把解锁放在析构函数是否可行?考虑到有不同的锁,于是写了一个抽象锁类,一个具体锁类和一个调用类,具体代码如下:

//抽象类class CLockObject{public:   CLockObject(){}   ~CLockObject(){}   virtual void Lock() = 0;   virtual void UnLock() = 0 ;};//具体锁,使用临界区举例class CMyCriticalSection : public CLockObject{public:   CMyCriticalSection()   {      InitializeCriticalSection(&m_section);   }   ~CMyCriticalSection()   {      DeleteCriticalSection(&m_section);   }   virtual void Lock()   {      EnterCriticalSection(&m_section);   }   virtual void UnLock()   {      LeaveCriticalSection(&m_section);   }private:    CRITICAL_SECTION m_section;};//利用析构函数解锁class CMyLock{ public:   CMyLock(CLockObject *pLock)   {      m_pLock = pLock;      m_pLock->Lock();   }   ~CMyLock()   {      m_pLock->UnLock();   } private:   CLockObject *m_pLock;}; 

对应的SetVal函数的第2版本代码如下:
int SetVal(int iVal){    CMyCriticalSection criLock ;     CMyLock myLock(&criLock);        if ( 1 == iVal )    {       g_iVal = 2;    //出口点,自动调用myLock.~CMyLock();       return 1;    }    else if( 2 == iVal)    {       g_iVal = 10;        return 2;   //出口点,自动调用myLock.~CMyLock();    }    else     {       g_iVal = 20;      }     return 0;  //出口点,自动调用myLock.~CMyLock();}