Повысить вопрос о контейнере shared_ptr - PullRequest
0 голосов
/ 22 сентября 2008

Допустим, у меня есть контейнер (std :: vector) указателей, используемых многопоточным приложением. При добавлении новых указателей в контейнер код защищается с помощью критического раздела (boost :: mutex). Все хорошо. Код должен иметь возможность возвращать один из этих указателей потоку для обработки, но другой отдельный поток может выбрать удаление одного из этих указателей, который все еще может использоваться. e.g.:

thread1()
{
    foo* p = get_pointer();
    ...
    p->do_something();
}

thread2()
{
    foo* p = get_pointer();
    ...
    delete p;
}

Таким образом, thread2 может удалить указатель, пока thread1 использует его. Противный.

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

std::vector<boost::shared_ptr<foo> > my_vec;

thread1()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    sp->do_something();
}

thread2()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    my_vec.erase(my_vec.begin());
}

boost::shared_ptr<foo> get_ptr(int index)
{
    lock_my_vec();
    return my_vec[index];
}

В приведенном выше примере, если поток1 получает указатель до того, как поток2 вызовет удаление, будет ли объект, на который указывает, все еще действительным? Это на самом деле не будет удалено, когда thread1 завершится? Обратите внимание, что доступ к глобальному вектору будет через критическую секцию.

Я думаю, что так работает shared_ptrs, но я должен быть уверен.

Ответы [ 3 ]

3 голосов
/ 22 сентября 2008

Для обеспечения безопасности потоков Boost :: shared_ptr вы должны проверить эту ссылку . Безопасность не гарантируется, но на многих платформах это работает. Изменение std :: vector не безопасно AFAIK.

1 голос
/ 22 сентября 2008

В приведенном выше примере, если поток1 получает указатель до того, как поток 2 вызовет удаление, будет ли объект, на который указывает, все еще действительным? На самом деле он не будет удален после завершения потока 1?

В вашем примере, если thread1 получает указатель перед thread2, то thread2 придется ждать в начале функции (из-за блокировки). Так что да, объект, на который указывает указатель, все еще будет действительным. Однако вам может потребоваться убедиться, что my_vec не пусто, прежде чем получить доступ к своему первому элементу.

0 голосов
/ 22 сентября 2008

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

...