Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When not to use RAII for resource management [closed]

Can anyone provide me with one or more concrete examples in which RAII was not the most efficient method for resource management, and why?

like image 755
IUnknownPointer Avatar asked Jul 21 '10 09:07

IUnknownPointer


People also ask

What is an advantage of using RAII over not using RAII?

Smart pointers use RAII to hide the manipulation of pointers, which are a lower level than business code, so RAII helps respect levels of abstraction in that case too. This is true for resource management in general, including database connection.

What is RAII and why is it important?

RAII is an important C++ idiom for resource management. Notably, RAII provides a structural idiom for proper resource management with exceptions. The power of the idiom is in the guarantees it provides. Properly used, the destructor for your RAII-object is guaranteed to be called to allow you to free resources.

Is RAII garbage collection?

RAII and GC solve problems in completely different directions. They are completely different, despite what some would say. Both address the issue that managing resources is hard. Garbage Collection solves it by making it so that the developer doesn't need to pay as much attention to managing those resources.

What does RAII do?

Resource Acquisition Is Initialization or RAII, is a C++ programming technique 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, database connection—anything that exists in limited supply) to the ...


2 Answers

The only case I can think of where RAII was not the solution is with multithreaded critical region lock management. In general it is advisable to acquire the critical region lock (consider that the resource) and hold it in a RAII object:

void push( Element e ) {
   lock l(queue_mutex);  // acquire on constructing, release on destructing
   queue.push(e);
}

But there are situations where you cannot use RAII for that purpose. In particular, if a variable used in a loop condition is shared by multiple threads, and you cannot hold the lock for the whole loop execution, then you must acquire and release the lock with a different mechanism:

void stop_thread() {
   lock l(control_mutex);
   exit = true;
}
void run() {
   control_mutex.acquire();
   while ( !exit ) { // exit is a boolean modified somewhere else
      control_mutex.release();
      // do work
      control_mutex.acquire();
   }
   control_mutex.release();
}

It might even be possible to use RAII by (ab)using operator, now that I think of, but I had never actually thought of it. But I guess this is not really natural:

void run() {
   while ( lock(control_mutex), !exit ) {
      // do work
   }
}

So I guess that the answer is that not that I can imagine...

EDIT: Other solutions for the same problem using RAII:

@Mark Ransom:

bool should_exit() const {
   lock l(mutex);
   return exit;
}
void run() {
   while ( !should_exit() ) {
      // do work
   }
}

@fnieto:

void run() {
   while (true) {
      {  lock l(mutex);
         if (exit) break;
      }
      // do work
   }
}
like image 99
David Rodríguez - dribeas Avatar answered Oct 20 '22 09:10

David Rodríguez - dribeas


Sometimes two-stage initialization (create, then init, then use) is needed.

Or even three-stage: in our product, there is a collection of independent objects, each running a thread and able to subscribe to any number of other objects (including itself) via priority-inheriting queues. Objects and their subscriptions are read from the config file at startup. At construction time, each object RAIIs everything it can (files, sockets, etc), but no object can subscribe to others because they are constructed in unknown order. So then after all objects are constructed there's the second stage where all connections are made, and third stage when, once all connections are made, the threads are let go and begin messaging. Likewise, shutdown is mutli-stage as well.

like image 1
Cubbi Avatar answered Oct 20 '22 09:10

Cubbi