C++中RAII用法学习笔记
1.定义
RAII是 Resource Acquisition Is Initialization
的缩写,它是面向对象语言中的一种惯用法。RAII要求资源的有效期与持有资源的对象生命周期严格绑定,即由对象构造函数完成资源分配(获取),同时由析构函数完成资源的释放,只要对象能正确地析构,就不会出现资源泄漏问题。
RAII主要作用是在不失代码简洁性的同时,可以很好地保证代码的异常安全性。
2.解决问题
- (1) 手动申请资源(new/malloc)后,用完了忘记释放(delete/free);
- (2) 多线程资源同步,上锁后(mutex.lock()),用完忘记解锁(mutex.unlock());
- (3) 启动子线程执行任务后,忘记让主线程等待子线程执行完毕;
// Problem #1
{
int *arr = new int[dynamicSize];
} // arr goes out of scope but we didn't delete it, we have a memory leak
// Problem #2
std::mutex globalMutex;
void funcCalledInMultipleThreads() {
globalMutex.lock();
// Code that runs in multiple threads...
} // We never unlocked the mutex, so this function will deadlock
// Problem #3
{
std::thread t1([]() {
std::cout << "In a thread" << std::endl;
// Do some stuff...
return 5;
});
} // Thread goes out of scope and is joinable, std::terminate is called
3.常见用法
- (1)
C++标准库中
lock_guard``便是用RAII方式控制互斥量:
template <class Mutex>
class lock_guard {
public:
lock_guard(Mutex &mutex) : mutex_(mutex) {
mutex_.lock();
}
~lock_guard() {
mutex_.unlock();
}
lock_guard(const lock_guard &) = delete;
lock_guard &operator=(const lock_guard &) = delete;
private:
Mutex &mutex_;
};
- 使用方法:
#include <mutex>
using std::mutex;
using std::lock_guard;
mutex g_mutex;
void access_critical_section() {
lock_guard<mutex> lock(g_mutex);
// *****
}
- (2) 写过网络服务器的应该都知道,MySQL连接池一般会封装一个RAII,具体可以参考代码:https://github.com/MirrorYuChen/Server/tree/master/source/Database
4.参考资料
- [1] RAII维基百科
- [2] What is RAII?