Вопрос

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

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

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

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

Поэтому вместо этого я хочу использовать контейнер Boost shared ptr.IIRC эти указатели будут подсчитываться по ссылкам, поэтому, пока я возвращаю общие ptr вместо необработанных указателей, удаление одного из контейнеров ФАКТИЧЕСКИ НЕ освободит его, пока последнее его использование не выйдет за пределы области видимости.т. е.

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

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

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

Это было полезно?

Решение

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

Другие советы

В приведенном выше примере, если thread1 получит указатель до того, как thread2 вызовет erase , будет ли объект, на который указано, по-прежнему действительным?На самом деле он не будет удален после завершения thread1?

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top