Выполняет ли std::tr1::shared_ptr взаимное исключение?

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

Я хочу заменить все это на std::tr1::shared_ptr<BYTE>. MSDN говорит, что:

Несколько потоков могут читать и записывать разные объекты shared_ptr одновременно, даже если объекты являются копиями, которые совместно владеют.

Все звучит хорошо, пока я не узнаю, что CRITICAL_SECTION из класса используется вне его, чтобы «заблокировать» его и изменить его содержимое взаимоисключающим образом. Хорошо, это нарушает инкапсуляцию, я хочу это изменить.

Я знаю, что shared_ptr гарантирует, что память будет освобождена, но гарантирует ли она взаимное исключение при записи в память?


person dario_ramos    schedule 24.08.2011    source источник
comment
shared_ptr не знает, что вы делаете с объектом, на который он указывает. Все, что вам гарантируется, это то, что сам контейнер общего указателя работает правильно, даже если он используется одновременно.   -  person Kerrek SB    schedule 25.08.2011


Ответы (1)


Вы должны обеспечить правильный доступ к данным, на которые указывает std::tr1::shared_ptr. Эти данные ваши. Это имеет значение только для std::tr1::shared_ptr, когда пришло время его удалить.

Что касается самого объекта std::tr1::shared_ptr, у вас есть следующие гарантии:

  • вы можете безопасно читать из одного и того же экземпляра из нескольких потоков;
  • вы можете безопасно изменять различные экземпляры shared_ptr из нескольких потоков, даже если экземпляры являются копиями (совместно использующими один и тот же счетчик ссылок или что-то еще);

Любой другой одновременный доступ (например, одновременное чтение и запись в один и тот же экземпляр) является поведением undefined.

Также обратите внимание, что shared_ptr в новом стандарте C++11 имеет специальный API для атомарного доступа.

person R. Martinho Fernandes    schedule 24.08.2011
comment
Что вы подразумеваете под гарантиями взаимного исключения? - person Kerrek SB; 25.08.2011
comment
Я понял, что элементы данных shared_ptr потокобезопасны, а внешние данные, то есть те, на которые указывает указатель, переданный конструктору shared_ptr, — нет. Я прав? - person dario_ramos; 25.08.2011
comment
@R Мартиньо: Хе-хе. На самом деле, моя реализация shared_ptr использует эти привлекательные атомарные числа для подсчета ссылок. Я был весьма поражен тем, сколько машин находится внутри этого невинного маленького класса, когда я впервые увидел его... - person Kerrek SB; 25.08.2011
comment
@dario: я добавил больше деталей. - person R. Martinho Fernandes; 25.08.2011