Search code examples
c++raii

How to deal with Resource-waiting in RAII


I'm new to C++, and I'm currently learning the RAII (Resource Acquisition is Initialization) pattern. I was curious how one would deal with resources that they needed to wait on.

In Java, something that might be done is:

MyClass obj = new MyClass();
new Thread(
    () -> obj.initialize(); // resource acquisition
).start()

...

if (obj.initialized()) {
    // Use object
}

In other words, we can perform a time-intensive resource-acquisition in the background.

How can we do that in C++, with RAII? Or is this a limitation with RAII?


Solution

  • RAII means that resources are defined by some object. Ideally, the constructor of that object gets the resource, and the destructor releases it. During the time when the object is valid, you can use the object to interact with the resource.

    If a resource "needs to be waited on", then by the rules of RAII, that means you don't have an object that represents that resource yet. You instead have an object that represents a resource that will be available in the future.

    Which is why C++ calls this type std::future. It's a template, with the argument being the type of the object whose creation you are waiting on.

    Conceptually, a future is just a means to forward an object (or exception) from the piece of code that generates it (possibly asynchronously) to the receiver.

    Now given your example, we need to remove initialize from MyClass and make that a function which returns a MyClass instance. It could be a static member of MyClass, or it could be just a namespace-scoped function.

    So the code would essentially look like this:

    auto future = std::async(initialize);
    
    ...
    
    if(future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
    {
      MyClass resource = future.get(); //The `future` is now empty. Any exceptions will be thrown here.
    
      //use resource
    }