RAII

来源:互联网 发布:handler机制的源码分析 编辑:程序博客网 时间:2024/06/10 07:12

1.什么是RAII ?

RAII 的全称是“Resource Acquire Is Initial”。这是C++创始人Bjarne Stroustrup发明的词汇,比较令人费解。说起来,RAII的含义倒也不算复杂。用白话说就是:在类的构造函数中分配资源,在析构函数中释放资源。这样,当一个对象创建的时候,构造函数会自动地被调用;而当这个对象被释放的时候,析构函数也会被自动调用。于是乎,一个对象的生命期结束后将会不再占用资源,资源的使用是安全可靠的。

     RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。 
  RAII 的一般做法是这样的:在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做法有两大好处: 

  • 不需要显式地释放资源。 
  • 采用这种方式,对象所需的资源在其生命期内始终保持有效。


2.实战应用: scope lock (局部锁技术) 

     在很多时候,为了实现多线程之间的数据同步,我们会使用到 mutex,critical section,event,singal 等技术。但在使用过程中,由于各种原因,有时候,我们会遇到一个问题:由于忘记释放(Unlock)锁,产生死锁现象。采用RAII 就可以很好的解决这个问题,使用着不必担心释放锁的问题. 

示例代码如下:


//ILock.h#ifndef _ILOCK_H#define _ILOCK_Hclass ILock{public:ILock(void){};~ILock(void){};virtual void Lock() = 0;virtual void Unlock() = 0;};#endif

//LockAgency.h#ifndef _LOCKAGENCY_H#define _LOCKAGENCY_H#include <windows.h>#include "ILock.h"class LockAgency: public ILock{public:LockAgency(void);~LockAgency(void);void Lock();void Unlock();private:HANDLE m_Handle;};#endif

//LockAgency.cpp#include "LockAgency.h"LockAgency::LockAgency(void){m_Handle = ::CreateMutex(NULL, false, NULL);}LockAgency::~LockAgency(void){::CloseHandle(m_Handle);}void LockAgency::Lock(){::WaitForSingleObject(m_Handle, INFINITE);}void LockAgency::Unlock(){::ReleaseMutex(m_Handle);}

//Lock.h#ifndef _LOCK_H#define _LOCK_H#include "ILock.h"class Lock{public:Lock(ILock& lock);~Lock(void);private:ILock& m_Lock;};#endif

//Lock.cpp#include "Lock.h"Lock::Lock(ILock& lock): m_Lock(lock){m_Lock.Lock();}Lock::~Lock(void){m_Lock.Unlock();}

//LockTester.h#ifndef _LOCKTESTER_H#define _LOCKTESTER_H#include <iostream>#include "LockAgency.h"#include "Lock.h"using namespace std;class LockTester{public:LockTester(void);~LockTester(void);void Test();void Func_NeedLock();private:LockAgency m_LockAgency;};#endif

//LockTester.cpp#include "LockTester.h"LockTester::LockTester(void){}LockTester::~LockTester(void){}void LockTester::Test(){cout<<"LockTester::Test()...."<<endl<<endl;Func_NeedLock();}void LockTester::Func_NeedLock(){Lock lock(m_LockAgency);cout<<"Doing something....(These code need to be locked)"<<endl;}

//Main.cpp#include <iostream>#include "LockTester.h"using namespace std;int main(int argc, char* argv[]){LockTester tester;tester.Test();getchar();return 0;}



原创粉丝点击