RAII (Resource Acquisition Is Initialization)
원문: https://en.cppreference.com/w/cpp/language/raii
RAII - cppreference.com
Resource Acquisition Is Initialization or RAII, is a C++ programming technique[1][2] which binds the life cycle of a resource that must be acquired before use (allocated heap memory, thread of execution, open socket, open file, locked mutex, disk space, da
en.cppreference.com
RAII ??
RAII는 리소스의 생명주기를 객체를 통해서 관리하는 기법으로,
흔히, 힙 메모리, 스레드, 소켓, 파일, 뮤텍스, 데이터베이스연결 등의
리소스를 객체 안에서 관리를 하다가 객체의 생명주기가 끝나고,
소멸 되면서, 소멸자가 호출될 때 함께 내부의 리소스를 해제하는 패턴이다.
아래 예제에서는 RAII를 사용한 예와 그렇지 않은 나쁜 예를 비교해서 보여준다.
std::mutex m;
void bad()
{
m.lock(); // acquire the mutex
f(); // if f() throws an exception, the mutex is never released
if(!everything_ok()) return; // early return, the mutex is never released
m.unlock(); // if bad() reaches this statement, the mutex is released
}
void good()
{
std::lock_guard<std::mutex> lk(m); // RAII class: mutex acquisition is initialization
f(); // if f() throws an exception, the mutex is released
if(!everything_ok()) return; // early return, the mutex is released
}
std::lock_guard<>는 RAII 클래스로 mutex리소스의 잠금(lock), 해제(unlock) 처리가
구현되어있다. 라이브러리 내부로 가면 구현체를 볼 수 있다.
template <class _Mutex>
class _NODISCARD lock_guard { // class with destructor that unlocks a mutex
public:
using mutex_type = _Mutex;
explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock
_MyMutex.lock();
}
lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) {} // construct but don't lock
~lock_guard() noexcept {
_MyMutex.unlock();
}
lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;
private:
_Mutex& _MyMutex;
};
표준 라이브러리
자체 리소스를 관리하는 C++의 라이브러리 클래스들은 RAII 를 따르고 있다.
위의 std::lock_guard 뿐만아니라 아래와 같은 것들이 존재한다.
**메모리 관리
std::unique_ptr
std::shared_ptr
**뮤텍스 관리
std::lock_guard
std::unique_lock
std::shared_lock