std:: atomic <std::shared_ptr>
|
Определено в заголовке
<memory>
|
||
|
template
<
class
T
>
struct std:: atomic < std:: shared_ptr < T >> ; |
(начиная с C++20) | |
Частичная специализация шаблона
std::atomic
для
std::
shared_ptr
<
T
>
позволяет пользователям атомарно манипулировать объектами
shared_ptr
.
Если несколько потоков выполнения обращаются к одному и тому же объекту std::shared_ptr без синхронизации и любое из этих обращений использует неконстантную функцию-член shared_ptr , возникнет гонка данных, если все такие обращения не выполняются через экземпляр std:: atomic < std:: shared_ptr > (или, устаревший с C++20, через автономные функции для атомарного доступа к std::shared_ptr ).
Связанные инкременты
use_count
гарантированно являются частью атомарной операции. Связанные декременты
use_count
упорядочены после атомарной операции, но не обязаны быть её частью, за исключением изменения
use_count
при перезаписи
expected
в неудачной операции CAS. Любое связанное удаление и освобождение памяти упорядочены после шага атомарного обновления и не являются частью атомарной операции.
Обратите внимание, что управляющий блок
shared_ptr
является потокобезопасным: различные неатомарные объекты
std::shared_ptr
могут быть доступны с использованием изменяющих операций, таких как
operator
=
или
reset
, одновременно из нескольких потоков, даже если эти экземпляры являются копиями и совместно используют один и тот же управляющий блок внутри.
Тип T может быть неполным типом.
Типы членов
| Тип члена | Определение |
value_type
|
std:: shared_ptr < T > |
Функции-члены
Все неспециализированные std::atomic функции также предоставляются этой специализацией, и никаких дополнительных функций-членов не предусмотрено.
|
constexpr
atomic
(
)
noexcept
=
default
;
|
(1) | |
|
constexpr
atomic
(
std::
nullptr_t
)
noexcept
:
atomic
(
)
{
}
|
(2) | |
|
atomic
(
std::
shared_ptr
<
T
>
desired
)
noexcept
;
|
(3) | |
|
atomic
(
const
atomic
&
)
=
delete
;
|
(4) | |
|
void
operator
=
(
const
atomic
&
)
=
delete
;
|
(1) | |
|
void
operator
=
(
std::
shared_ptr
<
T
>
desired
)
noexcept
;
|
(2) | |
|
void
operator
=
(
std::
nullptr_t
)
noexcept
;
|
(3) | |
|
bool
is_lock_free
(
)
const
noexcept
;
|
||
Возвращает true если атомарные операции над всеми объектами данного типа являются lock-free, false в противном случае.
|
void
store
(
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
||
Атомарно заменяет значение * this значением desired как если бы с помощью p. swap ( desired ) , где p является базовым std:: shared_ptr < T > . Память упорядочивается в соответствии с order . Поведение не определено, если order равен std::memory_order_consume , std::memory_order_acquire или std::memory_order_acq_rel .
|
std::
shared_ptr
<
T
>
load
(
std::
memory_order
order
=
std::
memory_order_seq_cst
)
const
noexcept
;
|
||
Атомарно возвращает копию базового умного указателя. Память упорядочивается в соответствии с order . Поведение не определено, если order равен std::memory_order_release или std::memory_order_acq_rel .
|
std::
shared_ptr
<
T
>
exchange
(
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
||
Атомарно заменяет базовый std:: shared_ptr < T > на desired как если бы с помощью p. swap ( desired ) , где p - это базовый std:: shared_ptr < T > , и возвращает копию значения, которое p имел непосредственно перед обменом. Память упорядочивается согласно order . Это атомарная операция чтения-модификации-записи.
|
bool
compare_exchange_strong
(
std::
shared_ptr
<
T
>
&
expected,
std::
shared_ptr
<
T
>
desired,
std:: memory_order success, std:: memory_order failure ) noexcept ; |
(1) | |
|
bool
compare_exchange_weak
(
std::
shared_ptr
<
T
>
&
expected,
std::
shared_ptr
<
T
>
desired,
std:: memory_order success, std:: memory_order failure ) noexcept ; |
(2) | |
|
bool
compare_exchange_strong
(
std::
shared_ptr
<
T
>
&
expected,
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
(3) | |
|
bool
compare_exchange_weak
(
std::
shared_ptr
<
T
>
&
expected,
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
(4) | |
use_count
для
expected
является частью этой атомарной операции, хотя сама запись (и любое последующее освобождение/уничтожение) не обязаны быть таковыми.
fail_order
совпадает с
order
за исключением того, что
std::memory_order_acq_rel
заменяется на
std::memory_order_acquire
, а
std::memory_order_release
заменяется на
std::memory_order_relaxed
.
fail_order
совпадает с
order
за исключением того, что
std::memory_order_acq_rel
заменяется на
std::memory_order_acquire
, а
std::memory_order_release
заменяется на
std::memory_order_relaxed
.
|
void
wait
(
std::
shared_ptr
<
T
>
old,
std:: memory_order order = std:: memory_order_seq_cst ) const noexcept ; |
||
Выполняет атомарную операцию ожидания.
Сравнивает
load
(
order
)
с
old
и если они эквивалентны, то блокируется до тех пор, пока
*
this
не будет уведомлен с помощью
notify_one()
или
notify_all()
. Это повторяется до тех пор, пока
load
(
order
)
не изменится. Эта функция гарантированно возвращает управление только если значение изменилось, даже если базовая реализация разблокируется ложным образом.
Память упорядочивается в соответствии с order . Поведение не определено, если order равен std::memory_order_release или std::memory_order_acq_rel .
Примечание: два
shared_ptr
эквивалентны, если они хранят один и тот же указатель и либо совместно владеют объектом, либо оба пусты.
|
void
notify_one
(
)
noexcept
;
|
||
Выполняет атомарную операцию уведомления.
Если существует поток, заблокированный в операциях атомарного ожидания (т.е.
wait()
) на
*
this
, то разблокирует по крайней мере один такой поток; в противном случае не делает ничего.
|
void
notify_all
(
)
noexcept
;
|
||
Выполняет атомарную операцию уведомления.
Разблокирует все потоки, заблокированные в атомарных операциях ожидания (т.е.
wait()
) на
*
this
, если таковые имеются; в противном случае ничего не делает.
Константы-члены
Единственная стандартная
std::atomic
константа-член
is_always_lock_free
также предоставляется этой специализацией.
|
static
constexpr
bool
is_always_lock_free
=
/*implementation-defined*/
;
|
||
Примечания
| Макрос тестирования возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_atomic_shared_ptr
|
201711L
|
(C++20) |
std::atomic<std::shared_ptr>
|
Пример
|
Этот раздел не завершён
Причина: отсутствует пример |
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3661 | C++20 |
atomic<shared_ptr<T>>
was not constant-initializable from
nullptr
|
made constant-initializable |
| LWG 3893 | C++20 |
LWG3661
made
atomic<shared_ptr<T>>
not assignable from
nullptr_t
|
assignability restored |
Смотрите также
|
(C++11)
|
шаблон класса atomic и специализации для bool, целочисленных,
чисел с плавающей запятой,
(since C++20)
и указательных типов
(шаблон класса) |