简体   繁体   中英

Boost shared pointers C++ : shared pointer unable to free resource on release

I'm running into a problem where I can't get rid of the last shared pointer and I kinda need it actually.

So what I have is a manager and some worker threads. The manager keeps a collection of shared pointers to different resources. A worker may ask the manager for a shared pointer to a resource. There will always be 1 or more workers with a shared pointer to the resource. My end goal is that when all workers are done with the resource, the resource is deleted. However, in this scheme, the manager always maintains a shared pointer to the resource so even when no workers are hanging on to the shared pointer, the resource won't get deleted b/c the ref count should always be at least 1 since the manager is hanging onto it. I need the manager to hang on to a shared pointer to the reference so that if any worker comes asking for a shared pointer, the manager will be able to provide it one.


edit: When the resource is created a worker already has it. So at its creation its ref count should be two (manager has it, and a single worker has it). When the ref count hits one (only the manager has it), I would like it to be deleted. If the resource had already been deleted and a worker comes looking for it, the resource shall be recreated.


edit2: some code:

SomeSharedPointer Manager::getResource(String unique_id) 
{ // if unique id exists, return its mapped shared pointer, if unique id doesn't exist, create the resource, assign it a shared pointer, and stick it in the map 
}


class Worker
{
    SomeSharedPointer my_sp;

    Worker()
    {
       String someUniqueId = "http://blah.com"
       my_sp = Manager::getResource(someUniqueId);
       // do some work on the resource
    }

    ~Worker()
    {
        my_sp.reset(); // done with resource
    }
}

Why is the manager holding a shared_ptr (strong reference) to the object if it doesn't need to retain control, only pass it on? Not seeing your code, it seems like having the manager hold a weak_ptr and then pass that on to the workers, who lock it into a shared_ptr on their end. That will allow the manager to pass on references without owning one of its own.

class Worker
{
    SomeSharedPointer my_sp;

    Worker()
    {
        String someUniqueId = "http://blah.com"
        weak_ptr wp = Manager::getResource(someUniqueId);
        my_sp = wp.lock();

        // do some work on the resource
    }

    ~Worker()
    {
        //my_sp.reset(); // handled automatically, as part of how shared pointers work
    }
}

If a worker finishes and releases the resource, it will be destroyed and the manager will no longer be able to hand out references (which can be tested in getResource and reloaded). This doesn't seem quite optimal, but is part of your design, so it should work like that well.

Edit: You could also have getResource return a shared pointer, and have the manager hold the weak pointer, attempt to lock, do checking/reloading internally, and then return the shared pointer. As weak_ptr s can't be directly created, that may work somewhat better.

On the other hand, you could provide a function to compliment the one providing the workers with the pointer that releases it and does count checking in the manager.

Use a weak pointer in the manager and shared pointer in the workers, when a worker comes asking for the pointer create a shared pointer using the lock method.

as in boost::shared_ptr fptr = weakfoo.lock();

if shared pointer is empty, the pointer has either been released by the last worker or has not been created yet and needs creating

I would definitely avoid any solutions that involve looking at the ref count... only pain will ensue :)

I think the following is key:

I need the manager to hang on to a shared pointer to the reference so that if any worker comes asking for a shared pointer , the manager will be able to provide it one.

You need to decide at which point no more workers can come asking for the shared pointer. Once you know that's the case, the master can simply reset its instance of the shared pointer, thereby releasing the reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM