- Resource Acquisition Is Initialization
Resource Acquisition Is Initialization, often referred to by the acronym RAII, is a popular design pattern in many object oriented languages like
C++ , D and Ada. The technique, invented byBjarne Stroustrup cite book
title = The Design and Evolution of C++
last = Stroustrup
first = Bjarne
authorlink = Bjarne Stroustrup
year = 1994
publisher = Addison-Wesley
id = ISBN 0-201-54330-3] , associates acquisition of resources with the initialization of objects that release the resources upon destruction.RAII involves assigning ownership of a resource to scoped objects for resource managementcite paper
title = Exception Safety: Concepts and Techniques
author = Bjarne Stroustrup
url = http://www.research.att.com/~bs/except.pdf
date = April 2001
format =PDF
accessdate = 2007-09-02 ] . The acquisition is typically bound to the construction (initialization) and the automatic, deterministic destruction (uninitialization) is used to guarantee the resource is released. Since scoped objects are cleaned up regardless of whether the scope exits through normal use or through an exception, RAII is a key concept for writingexception-safe code [cite book
last = Sutter
first = Herb
authorlink = Herb Sutter
year = 1999
title = Exceptional C++
publisher = Addison-Wesley
id = ISBN 0-201-61562-2] .RAII is widely used to ensure exception safety. RAII makes it possible to avoid resource leaks without extensive use of exception handling blocks to release resources before permitting exceptions to propagate.
Language Support
C++ and D allow objects to be allocated on the stack, so the language scoping mechanism ensures that destructors are called when a local object's scope ends. By putting the resource release logic in the destructor, C++'s and D's scoping provide direct support for RAII.Typical uses
The RAII technique is often used for controlling thread locks in multi-threaded applications. In that use, the object releases the lock, if held, when destroyed. Another typical example is file management, wherein the file class closes the associated file, if open, when destroyed.
The ownership of dynamically allocated memory (such as memoryallocated with new in C++ code) can be controlled withRAII, such that the memory is released when the RAII object isdestroyed. For this purpose, the C++ Standard Library defines. Furthermore, lifetime of sharedobjects can be managed by a smart pointer with shared-ownershipsemantics such as
boost::shared_ptr
, defined in C++by Boost and marked for inclusion in the newC++0x standard, or by policy based smart pointers such asLoki::SmartPtr
from Loki.Mutability (C++)
In C++, an important consideration of classes that implement RAII is their mutabilitycite book
last = Wilson
first = Matthew
authorlink = Matthew Wilson
year = 2004
title = Imperfect C++
publisher = Addison-Wesley
id = ISBN 0-321-22877-4] . A class exhibiting "mutable RAII" provides facilitiesfor instances to be assigned a new resource; one that exhibits"immutable RAII" does not. An example of the former is; examples of the latter are theSTLSoft library'sstlsoft::scoped_handle
and
Boost.SmartPtr'sboost::scoped_ptr
.Classes exhibiting "immutable RAII" are considerably easier to implement in C++, since the design need not account for assignment (including copy-assignment), except to explicitly prohibit it. Consider the following RAII class template that illustrates the simplicity of implementing "immutable RAII". Compare this with the implementation of or another "mutable RAII" smart pointer, which will have many more member functions and logic to handle premature release in cases of self-assignment.
C++ example
The following RAII class is a lightweight wrapper of the
C standard library file system calls.Class
file
can then be used as follows:This works because the class
file
encapsulates the management of theFILE*
file handle. When objectsfile
are local to a function, C++ guarantees that they are destroyed at the end of the enclosing scope (the function in the example), and thefile
destructor releases the file by callingstd::fclose(file_)
. Furthermore,file
instances guarantee that a file is available by throwing an exception if the file could not be opened when creating the object.Local variables easily manage multiple resources within a single function: They are destroyed in the reverse order of their construction, and an object is only destroyed if fully constructed. That is, if no exception propagates from its constructor.
Using RAII-enabled resources simplifies and reduces overall code size and helps ensure program correctness.
Resource management without RAII
In Java, objects are not values and must be accessed through references; hence you cannot have automatic variables of objects that "go out of scope." Instead, all objects are dynamically allocated and have indefinite lifetimes, given Java's use of garbage collection which reclaims objects at indeterminate times, if at all. Resources must thus be closed manually by the programmer. The preceding example would be written like this:
The burden of releasing resources falls on the programmer each time a resource is used.
Ruby and
Smalltalk do not support RAII, but have a simpler and more flexible pattern that makes use of methods that pass resources to closure blocks. Here is an example in Ruby:The
open
method ensures that the file handle is closed without special precautions by the code writing to the file. This is similar toCommon Lisp 's [http://www.lispworks.com/documentation/HyperSpec/Body/s_unwind.htm 'unwind-protect'] -based macros.Python's [http://www.python.org/dev/peps/pep-0343/ 'with' statement] and the in C# and Visual Basic 2005 provide deterministic resource management within a block and do away with the requirement for explicit
finally
-based cleanup and release.Perl manages object lifetime by
reference counting , making it possible to use RAII in a limited form. Objects that are no longer referenced are immediately released, so a destructor can release the resource at that time. However, object lifetime isn't necessarily bound to any lexical scope. One can store a reference to an object in a global variable, for example, thus keeping the object (and resource) alive indeterminately long. This makes it possible to accidentally leak resources that should have been released at the end of some scope.C requires significant administrative code since it doesn't support exceptions, try-finally blocks or RAII of any kind. A typical approach is to separate releasing of resources at the end of the function and jump there with gotos in the case of error. This way the cleanup code need not be duplicated.
Variations exist, but the example illustrates the general approach.
References
External links
*Article " [http://www.hackcraft.net/raii/ The RAII Programming Idiom] " by
Wikipedia editor Jon Hanna (Talliesin)
*Wiki [http://c2.com/cgi/wiki?ResourceAcquisitionIsInitialization "Resource Acquisition Is Initialization"] from the Portland Pattern Repository
*Sample Chapter " [http://www.informit.com/articles/article.aspx?p=30642&seqNum=8 Gotcha #67: Failure to Employ Resource Acquisition Is Initialization] " by Stephen Dewhurst
*Interview " [http://artima.com/intv/modern3.html A Conversation with Bjarne Stroustrup] " by Bill Venners
*Article " [http://artima.com/cppsource/bigtwo3.html The Law of The Big Two] " by Bjorn Karlsson and Matthew Wilson
*Blog Entry " [http://jrdodds.blogs.com/blog/2004/08/raii_in_c.html RAII in C++] " by Jonathan Dodds
*Article " [http://gethelp.devx.com/techtips/cpp_pro/10min/2001/november/10min1101.asp Implementing the 'Resource Acquisition is Initialization' Idiom] " by Danny Kalev
*Article " [http://sourceforge.net/docman/display_doc.php?docid=8673&group_id=9028 RAII] " by Mike Nordell
*Article " [http://www.codeproject.com/KB/cpp/RAIIFactory.aspx RAII, Dynamic Objects, and Factories in C++] " by Roland Pibinger
*Article " [http://www.ddj.com/184409895 Managing Dynamic Objects in C++] " by Tom Cargill
*Blog " [http://tombarta.wordpress.com/tag/raii/ tombarta RAII] "
*Blog Entry " [http://waelchatila.com/2005/10/06/1128588184677.html RAII C++ Anti-Pattern] "
*Article " [http://www.onlamp.com/pub/a/onlamp/2006/05/04/smart-pointers.html Smart pointers in C++] " by Julio M. Merino Vidal
*Blog Entry " [http://beautifulcode.oreillynet.com/2008/04/resource_management_a_critical.php Resource Management: A Critical Look at RAII] " by Michael Feathers
Wikimedia Foundation. 2010.