Повышение общих указателей C ++: общий указатель не может освободить ресурс при выпуске - PullRequest
1 голос
/ 14 октября 2011

У меня проблема с тем, что я не могу избавиться от последнего общего указателя, и мне это действительно нужно.

Итак, у меня есть менеджер и некоторые рабочие потоки.Менеджер хранит коллекцию общих указателей на разные ресурсы.Работник может запросить у менеджера общий указатель на ресурс.Всегда будет 1 или более работников с общим указателем на ресурс.Моя конечная цель состоит в том, чтобы, когда все работники сделали с ресурсом, ресурс был удален.Однако в этой схеме менеджер всегда поддерживает общий указатель на ресурс, поэтому, даже если ни один работник не привязан к общему указателю, ресурс не будет удален, так как счетчик ссылок всегда должен быть не менее 1, так какменеджер висит на нем.Мне нужно, чтобы менеджер держался за общий указатель на ссылку, чтобы, если кто-то из рабочих пришел с просьбой об общем указателе, менеджер мог его предоставить.


edit: Когда ресурс создан, он уже есть у работника.Таким образом, при его создании количество ссылок должно быть два (у менеджера есть, а у одного работника).Когда количество ссылок достигает одного (только у менеджера), я бы хотел, чтобы он был удален.Если ресурс уже был удален и его ищет работник, ресурс должен быть воссоздан.


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
    }
}

Ответы [ 3 ]

3 голосов
/ 14 октября 2011

Почему менеджер держит shared_ptr (сильная ссылка) на объект, если ему не нужно сохранять контроль, только передать его?Не видя ваш код, похоже, что менеджер держит weak_ptr, а затем передает его рабочим, которые фиксируют его на shared_ptr на своем конце.Это позволит менеджеру передавать ссылки, не имея собственных.

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
    }
}

Если работник заканчивает работу и освобождает ресурс, он будет уничтожен, и менеджер больше не сможет раздавать ссылки.(который можно проверить в getResource и перезагрузить).Это не кажется оптимальным, но это часть вашего дизайна, поэтому он должен работать так же хорошо.

Редактировать: Вы также можете getResource вернуть общий указатель, ипопросите менеджера удерживать слабый указатель, попытаться заблокировать, выполнить внутреннюю проверку / перезагрузку, а затем вернуть общий указатель.Поскольку weak_ptr не могут быть созданы напрямую, это может работать несколько лучше.

С другой стороны, вы можете предоставить функцию, дополняющую ту, которая предоставляет работникам указатель, который освобождает его и считаетпроверка в менеджере.

1 голос
/ 14 октября 2011

Используйте слабый указатель в менеджере и общий указатель в рабочих, когда работник приходит с запросом на указатель, создайте общий указатель, используя метод блокировки.

как в boost :: shared_ptr fptr = weakfoo.lock ();

если разделяемый указатель пуст, указатель был освобожден последним работником или еще не был создан и требуетсоздание

Я бы определенно избегал любых решений, связанных с просмотром подсчета ссылок ... будет только боль :)

0 голосов
/ 14 октября 2011

Я думаю, что следующее является ключевым:

Мне нужно, чтобы менеджер держался за общий указатель на ссылку, чтобы , если кто-нибудь из рабочих пришел с просьбой об общем указателе , менеджер смог предоставить его.

Вам нужно решить, в какой момент больше не могут приходить работники с общим указателем. Как только вы узнаете, что это так, мастер может просто сбросить свой экземпляр общего указателя, освободив тем самым ссылку.

...