Linux学习之互斥量的封装二:封装临界区
本节在上一节的基础上,利用局部变量的构造和析构函数的特性,封装了对临界区的加锁和解锁操作,保证了程序(线程)在异常终止或中途退出的情况下也能正确解锁,从而不会出现死锁。
增加的临界区类"CLCriticalSection",其它源代码同上一节。
头文件:
View Code
#ifndef CLCriticalSection_H
#define CLCriticalSection_H
class CLMutex;
class CLCriticalSection
{
public:
/*
出错时构造函数和析构函数将会抛出字符串类型异常
*/
CLCriticalSection(CLMutex *pMutex);
virtual ~CLCriticalSection();
private:
CLCriticalSection(const CLCriticalSection&);
CLCriticalSection& operator=(const CLCriticalSection&);
private:
CLMutex *m_pMutex;
};
#endif
实现:
View Code
#include "CLCriticalSection.h"
#include "CLMutex.h"
#include "CLLog.h"
#include "CLStatus.h"
CLCriticalSection::CLCriticalSection(CLMutex *pMutex)
{
if(pMutex == 0)
{
CLLog::WriteLogMsg("In CLCriticalSection::CLCriticalSection(), pMutex == 0", 0);
throw "error";
}
m_pMutex = pMutex;
CLStatus s = m_pMutex->Lock();
if(!s.IsSuccess())
{
CLLog::WriteLogMsg("In CLCriticalSection::CLCriticalSection(), m_pMutex->Lock error", 0);
throw "error";
}
}
CLCriticalSection::~CLCriticalSection()
{
if(m_pMutex != 0)
{
CLStatus s = m_pMutex->Unlock();
if(!s.IsSuccess())
{
CLLog::WriteLogMsg("In CLCriticalSection::~CLCriticalSection(), m_pMutex->Unlock error", 0);
throw "error";
}
}
}
注意,该类仅负责对互斥量的加锁(加锁时附带了对互斥量的有效性检测)和解锁操作(实际还是调用CLMutext的操作),而锁的创建和销毁仍由CLMutex类完成(由构造和析构函数完成)。
测试:
View Code
#include <iostream>
#include <unistd.h>
#include "CLThread.h"
#include "CLExecutiveFunctionProvider.h"
#include "CLMutex.h"
#include "CLCriticalSection.h"
using namespace std;
struct SPara
{
int Flag;
CLMutex mutex;
};
class CLMyFunction : public CLExecutiveFunctionProvider
{
public:
CLMyFunction()
{
}
virtual ~CLMyFunction()
{
}
void test()
{
throw 32;
}
virtual CLStatus RunExecutiveFunction(void *pContext)
{
try
{
SPara *p = (SPara*)pContext;
CLCriticalSection cs(&(p->mutex));
p->Flag++;
test();
}
catch(...)
{
cout << "exception" << endl;
}
return CLStatus(0, 0);
}
};
int main()
{
CLExecutiveFunctionProvider *myfunction = new CLMyFunction();
CLExecutive *pThread = new CLThread(myfunction);
SPara *p = new SPara;
p->Flag = 3;
pThread->Run((void *)p);
sleep(2);
{
CLCriticalSection cs(&(p->mutex));
p->Flag++;
cout << p->Flag << endl;
}
pThread->WaitForDeath();
delete p;
delete pThread;
delete myfunction;
return 0;
}