Пространства имён
Варианты
Действия

std::atomic<std::shared_ptr>

Материал из cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
Библиотека утилит
Языковая поддержка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования функциональности библиотеки (C++20)    
Управление динамической памятью
Программные утилиты
Поддержка сопрограмм(C++20)
Вариативные функции
Трёхстороннее сравнение (C++20)
(C++20)
(C++20)(C++20)(C++20)(C++20)(C++20)(C++20)
Общие утилиты
Дата и время
Функциональные объекты
Библиотека форматирования(C++20)
(C++11)
Операторы отношения (устарело в C++20)
Целочисленные функции сравнения
(C++20)(C++20)(C++20)    
(C++20)
Операции обмена и типа
(C++11)
(C++11)
(C++17)
Общие лексические типы
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Элементарные преобразования строк
(C++17)
(C++17)
 
Динамическое управление памятью
no section name
Ограниченные алгоритмы неинициализированной памяти
no section name
Поддержка сбора мусора
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)



no section name
 
 
Определено в заголовочном файле <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_typestd::shared_ptr<T>

[править]Функции-элементы

Все неспециализированные функции std::atomic также предоставляются этой специализацией и не содержат дополнительных функций-элементов.

atomic<shared_ptr<T>>::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)
1,2) Инициализирует базовый shared_ptr<T> нулевым значением.
3) Инициализирует базовый shared_ptr<T> копией desired. Как и в случае любого типа std::atomic, инициализация не является атомарной операцией.
4) Атомарные типы нельзя копировать/перемещать

atomic<shared_ptr<T>>::operator=

void operator=(const atomic&)= delete;
(1)
void operator=(std::shared_ptr<T> desired )noexcept;
(2)
void operator=(std::nullptr_t)noexcept;
(3)
1) Атомарные типы нельзя копировать\перемещать присваиванием
2) Присваивание значения эквивалентно store(desired)
3) Сбрасывает атомарный общий указатель к нулевому значению указателя. Эквивалентно store(nullptr);.

atomic<shared_ptr<T>>::is_lock_free

bool is_lock_free()constnoexcept;

Возвращает true, если атомарные операции над всеми объектами этого типа не блокируются, иначе false.

atomic<shared_ptr<T>>::store

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.

atomic<shared_ptr<T>>::load

Атомарно возвращает копию базового общего указателя. Память упорядочена в соответствии с order. Поведение не определено, если order равно std::memory_order_release или std::memory_order_acq_rel.

atomic<shared_ptr<T>>::operator std::shared_ptr<T>

operator std::shared_ptr<T>()constnoexcept;

Эквивалентно return load();

atomic<shared_ptr<T>>::exchange

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. Это атомарная операция чтения-изменения-записи.

atomic<shared_ptr<T>>::compare_exchange_weak, compare_exchange_strong

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)
1) Если базовый std::shared_ptr<T> хранит тот же T*, что и expected, и разделяет с ним владение, или если и базовый, и expected пусты, присваивает значение из desired базовому std::shared_ptr<T>, возвращает true и упорядочивает память в соответствии с success, иначе присваивает из базового std::shared_ptr<T> в expected, возвращает false и упорядочивает память в соответствии с failure. Поведение не определено, если failure равно std::memory_order_release или std::memory_order_acq_rel. В случае успеха операция является атомарной операцией чтения-изменения-записи для *this, а доступ к expected после атомарного обновления невозможен. В случае сбоя операция представляет собой атомарную операцию загрузки *this, а expected обновляется существующим значением, считанным из атомарного объекта. Это обновление use_count для expected является частью этой атомарной операции, хотя сама запись (и любое последующее освобождение/уничтожение) не требуется.
2) То же, что и (1), но также может привести к ложному сбою.
3) Эквивалентно: return compare_exchange_strong(expected, desired, order, fail_order);, где fail_order совпадает с order, за исключением того, что std::memory_order_acq_rel заменяется на std::memory_order_acquire, а std::memory_order_release заменяется на std::memory_order_relaxed.
4) Эквивалентно: return compare_exchange_weak(expected, desired, order, fail_order); где fail_order совпадает с order, за исключением того, что std::memory_order_acq_rel заменяется на std::memory_order_acquire, а std::memory_order_release заменяется на std::memory_order_relaxed.

atomic<shared_ptr<T>>::wait

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 эквивалентны, если они хранят один и тот же указатель и либо совместно владеют, либо оба пусты.

atomic<shared_ptr<T>>::notify_one

void notify_one()noexcept;

Выполняет атомарную операцию уведомления.

Если есть поток, заблокированный в атомарных операциях ожидания (т.е. wait()) для *this, разблокирует по крайней мере один такой поток; иначе ничего не делает.

atomic<shared_ptr<T>>::notify_all

void notify_all()noexcept;

Выполняет атомарную операцию уведомления.

Разблокирует все потоки, заблокированные в атомарных операциях ожидания (т.е. wait()) для *this, если таковые имеются; иначе ничего не делает.

[править]Константы элементы

Единственная стандартная константа-элемент std::atomic это is_always_lock_free, также предоставляемая этой специализацией.

atomic<shared_ptr<T>>::is_always_lock_free

staticconstexprbool is_always_lock_free =/*определено-реализацией*/;

[править]Примечание

Макрос Тестирования функциональностиЗначениеСтандартФункциональность
__cpp_lib_atomic_shared_ptr201711L(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, целочисленных типов и указателей
(шаблон класса)[править]
close