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_H class 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; }