简体   繁体   English

Boost共享指针C ++:共享指针无法在释放时释放资源

[英]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. 但是,在此方案中,管理器始终维护一个指向资源的共享指针,因此即使没有工作者挂在共享指针上,资源也不会被删除b / c引用计数应始终至少为1,因为经理正在坚持下去。 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: edit2:一些代码:

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? 为什么管理器在不需要保留控制权的情况下持有对象的shared_ptr (强引用),只传递它? 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. 没有看到你的代码,似乎让经理持有一个weak_ptr ,然后将其传递给工人,工人将其锁定在他们端的shared_ptr上。 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). 如果一个worker完成并释放了资源,它将被销毁,并且管理器将不再能够getResource引用(可以在getResource测试并重新加载)。 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. 编辑:你也可以让getResource返回一个共享指针,并让管理器保持弱指针,尝试锁定,在内部进行检查/重新加载,然后返回共享指针。 As weak_ptr s can't be directly created, that may work somewhat better. 由于无法直接创建weak_ptr ,因此可能会更好一些。

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. 当一个worker要求指针使用lock方法创建一个共享指针时,在manager中使用一个弱指针和worker中的共享指针。

as in boost::shared_ptr fptr = weakfoo.lock(); 如在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. 一旦你知道了这种情况,master就可以简单地重置它的共享指针实例,从而释放引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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