std::atomic<std::shared_ptr>
Определено в заголовочном файле <memory> | ||
template<class T > structstd::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 можно получить с помощью mutable операций, таких как 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()constnoexcept; | ||
Возвращает true, если атомарные операции над всеми объектами этого типа не блокируются, иначе 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)constnoexcept; | ||
Атомарно возвращает копию базового общего указателя. Память упорядочена в соответствии с 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)constnoexcept; | ||
Выполняет атомарную операцию ожидания.
Сравнивает 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
, также предоставляемая этой специализацией.
staticconstexprbool is_always_lock_free =/*определено-реализацией*/; | ||
[править]Примечание
Макрос Тестирования функциональности | Значение | Стандарт | Функциональность |
---|---|---|---|
__cpp_lib_atomic_shared_ptr | 201711L | (C++20) | std::atomic<std::shared_ptr> |
[править]Пример
Этот раздел не завершён Причина: нет примера |
[править]Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
Номер | Применён | Поведение в стандарте | Корректное поведение |
---|---|---|---|
LWG 3661 | C++20 | atomic<shared_ptr<T>> не инициализировался константно изnullptr | сделан инициализируемым константно |
LWG 3893 | C++20 | LWG3661 сделало atomic<shared_ptr<T>> недоступным дляприсваивания из nullptr_t | возможность присваивания восстановлена |
[править]Смотри также
(C++11) | шаблон класса atomic и его специализации для bool, целочисленных типов и указателей (шаблон класса) |