Search code examples
c++cdesign-patternsraii

Is lock_guard a RAII implementation or it is used to implement RAII?


Wikipedia (and some other sources) states:

In RAII, holding a resource is tied to object lifetime: resource allocation (acquisition) is done during object creation (specifically initialization), by the constructor, while resource deallocation (release) is done during object destruction, by the destructor. If objects are destructed properly, resource leaks do not occur.

However, the example on wiki shows a code that don't show us the constructos/desctructors of the objects at all:

#include <string>
#include <mutex>
#include <iostream>
#include <fstream>
#include <stdexcept>

void write_to_file (const std::string & message) {
    // mutex to protect file access
    static std::mutex mutex;

    // lock mutex before accessing file
    std::lock_guard<std::mutex> lock(mutex);

    // try to open file
    std::ofstream file("example.txt");
    if (!file.is_open())
        throw std::runtime_error("unable to open file");

    // write message to file
    file << message << std::endl;

    // file will be closed 1st when leaving scope (regardless of exception)
    // mutex will be unlocked 2nd (from lock destructor) when leaving
    // scope (regardless of exception)
}

The definition I found for lock_guard also cites it is "RAII-style":

The class lock_guard is a mutex wrapper that provides a convenient RAII-style mechanism for owning a mutex for the duration of a scoped block.

On the example, the RAII is implemented on the mutex class, or in the lock_guard class? Or is not implemented on a class at all?


Solution

  • It is lock_guard who provides RAII for synchronization in the snippet you posted. mutex by its own doesn't follow the RAII idiom. RAII doesn't have to be provided by a separate object. For instance, std::ofstream provide both functionality for file output operation and RAII for the file state open\close. Is it a freedom left to the designer.

    RAII = Resource Acquisition Is Initialization

    ie Object creation implies resource acquisition and object destruction implies resource destruction. If you are doing acquisition or destruction somewhere else then you are not using RAII.