Quantcast
Channel: Abhijit Nadgouda @ iface » programming
Viewing all articles
Browse latest Browse all 35

Resource Acquisition Is Initialization

$
0
0

This post has already been published on code::gallery blog which now has been merged into this blog.

Software programs have to deal with resources (memory, files, mutexes, semaphores, database connections, …) that a computer provides. To be able to make sure that the resources are available to all the programs and optimally used, following steps are required to use a resource:

  • Acquire a resource
  • Use the resource
  • Release the resource

By acquiring and releasing the program stakes its claim to the resource. If the resource is not released it usually ends up causing memory leaks, deadlocks or sometimes crashes. Memory is the most commonly used resource and memory leaks are commonly witnessed. Resource Acquisition Is Initialization (RAII) is an idiom that provides a protocol for acquiring and releasing resources.

Encapsulates Allocation and Deallocation

The classes that are written usually provide a level of abstraction over the physical resources available. RAII allows us to encapsulate the acquisition and release of these resources. A popular example is that of using a database connection. If the connection is acquired from the connection pool and not released back, it finally runs out of the connections and applications cannot continue working with the database. This is more probable if you leave this responsibility to the user of your class (another programmer). Here is an example in C++, that uses RAII to acquire the connection and release it:

class MyRecords
{
    private:
       DBConn connection;

    public:
       MyRecords()
       {
           connection = new DBConn();
       }

       ~MyRecords()
       {
           delete connection ;
       }
}

When this class is used, it guarantees release of the connection when its destructor is called. The destructor can be explicitly called, but it is automatically invoked if it is used as a local variable and goes out of scope. Your user now does not need to worry about the database connection, nor do you have to worry if he/she has released the database connection which can lead to undersirable situations.

void useMyRecords()
{
    // Allocated on stack
    MyRecords records;

    ....

    // Will run out of scope beyond this method
}

The same can be applied to any resource that a program might work with.

Gives Control To You

RAII is just half the story, it also includes releasing the resource. For your user, the two different steps of initializing your object and acquiring the resource has been combined into one, in fact completely encapuslated. What this also means is that your user does not have to worry in unavoidable circumstances like exceptions. Stack variables automatically go out of scope and their destructors are invoked.

It is not always necessary to acquire a resource in the constructor, it might be done in any other intermediate methods. In this case, care should be taken to check if the resource acquisition was successful before releasing it.

Lesser and cleaner code is just one of the post-effects, the real benefit is that you, as owner of your class, get complete control of the resources that your class uses. This is exponentially beneficial if you author a library or a framework.

Where is it applicable?

RAII needs to be supported by a language to be used. Generally, a language which uses non-deterministic garbage collection, lika Java does not support RAII. If the language supports use of custom-defined types for local variables (automatic objects in C++), you can take advantage of the automatic invocation of destructors when they go out of scope. It is also supported by object models and languages like COM which relies on reference-counted garbage collection.

More reading:

Technorati tags: , , ,

Copyright Abhijit Nadgouda.



Viewing all articles
Browse latest Browse all 35

Trending Articles