Каким образом должен быть тема-unsafe shared_ptr?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Каким образом должен быть тема-unsafe shared_ptr?

Сообщение Anonymous »

Я в основном ищу кого -нибудь, чтобы дважды проверить мое чтение стандарта здесь.
tldr: требует ли стандарт, чтобы деструктор ared_ptr Заказ доступа к общему объекту до того, как деструктор этого объекта будет вызван в другом потоке? Потому что концептуально все, что делает Shared_ptr, это связывает справочный счетчик с объектом для управления своей жизнью. Выделенный объект по -прежнему доступен через обычный указатель (через get () или перегруженные -> или * операторы), поэтому у Shared_ptr нет никакого способа обеспечить какую -либо дополнительную защиту, даже если он хотел. < /P>
< P> Я был, однако, в предположении, что следующий код не будет содержать расу данных: < /p>

Код: Выделить всё

#include 
#include 
#include 

void foo(std::shared_ptr* in, std::binary_semaphore* flag, int* out)
{
int temp;
{
std::shared_ptr in_copy = *in; //copy shared ptr

flag->release(); //notify parent thread that copy has finished

temp = *in_copy; //read value from shared ptr

//in_copy is destructed
}

*out = temp; //copy value from shared ptr into out
}

int bar()
{
int out_value;
std::binary_semaphore flag{ 0 };
std::thread t1;
{
//create shared_ptr and pass to thread
std::shared_ptr in_value = std::make_shared(15);
t1 = std::thread{ &foo, &in_value, &flag, &out_value };

flag.acquire(); //wait for thread to copy shared_ptr

//in_value is destroyed
}
t1.join(); //wait for thread to finish

return out_value;
}
Специально, я обеспокоен тем, что строка *out = temp; может представлять собой расу данных, что будет иметь место, если компилятор мог бы на законных основаниях переместить первоначальное чтение Temp Off Outse Then Destructor Shared_ptr (по крайней мере, в случае, когда общий объект не разрушен на T1), что делает определение Foo эффективно (с некоторыми функциями разработки): < /p>

Код: Выделить всё

void foo(std::shared_ptr* in, std::binary_semaphore* flag, int* out)
{
//copy shared ptr
__refcount* in_refcount = in->get_refcount();
in_refcount->increment();
int* in_copy = in->get();

flag->release(); //notify parent thread that copy has finished

if (in_refcount->decrement_and_check_zero())
{
*out = *in_copy;
destroy in_copy;
}
else
{
*out = *in_copy;
}
}
Здесь есть раса данных в филиале Else, потому что возможно, что между вызовом к in_refcount-> derment_and_check_zero () и *in_copy есть возможность Для другого потока удалить объект shared_ptr, поэтому означает, что *in_copy может в конечном итоге читать с объекта, чья жизнь закончилась. юридическая трансформация? " Ни одна из трех крупных стандартных библиотечных реализаций не допускает этого, потому что в тех, что уменьшение отмены является операцией выпуска, поэтому предотвращает чтение temp = *in_copy для перемещения мимо деструктора Shared_ptr. Отношение возникает перед тем, как между прочтением и уменьшением оказания передачи, и, в силу того, что они условны в результате уменьшения удаления общего объекта также имеют отношение к уменьшению. Транзитивно это обеспечивает взаимосвязь между ними-точками, прежде чем передать чтение из общего объекта и его деструктором. /em> что такие отношения должны быть установлены. Заглядывая на стандарт, на заказывающих гарантизах Shared_ptr есть тревожная тишина. Все, что я могу видеть в отношении отношений shared_ptr с заказом Garantees: < /p>
из [util.smartptr.shared]: < /p>
  • Код: Выделить всё

    shared_ptr
    реализует семантику общей собственности; Последний оставшийся владелец указателя несет ответственность за уничтожение объекта
  • Изменения в использовании_COUNT () Не отражают изменения, которые могут вводить расы данных
    < /ul>
    и из [util.smartptr.shared.dest]: < /p>
  • После *this < /code> было уничтожен все экземпляры shared_ptr , которые общая владение с *this сообщит об use_count () , что на один меньше, чем его предыдущее значение
Все, что, похоже, эффективно дают ссылку на оценку аналогичной семантики shared_ptr для расслабленной атомики, хотя, в частности, не называя их атомными операциями. Отсутствие их именования в качестве атомных операций примечательно, потому что это означает, что мы не можем вернуться к стандартным правилам установления отношений между упорядочением межкол. и mutex :: unlock () shared_ptr, похоже, явно не вызывается как пример объекта с методами, которые действуют так, как если бы они были атомными объектами. < /p>
В основном я могу ' tse ничего в формулировке стандарта, который предоставляет какие -либо гарантии, что операции на объекте, принадлежащем chared_ptr (или любым другим объектам, чьи время жизни ограничены временем срока службы объекта, таких как объекты, принадлежащие уникально Общий объект) имеют отношение к тому, что это происходит, с призывом деструктора общего объекта в другом потоке, и, следовательно, любой код, использующий Shared_ptr Расходы данных между доступом объекта и деструктором объекта. Известно, что объект, принадлежащий chared_ptr Я не могу найти способ интерпретировать стандарт, в котором эти гарантии на заказ обязаны быть предоставленными самим shared_ptr. Так что я бы хотел, если бы кто -то мог указать мне, где именно я это неправильно читаю.

Подробнее здесь: https://stackoverflow.com/questions/794 ... osed-to-be
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»