Spec-Zone.ru › C++

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 при переопределении expected в случае неудачной операции CAS. Любые связанные операции удаления и выделения памяти выполняются после шага атомарного обновления и не являются частью атомарной операции.

Обратите внимание, что блок управления объектом shared_ptr защищён от одновременного доступа из разных потоков: к различным неатомарным объектам std::shared_ptr можно обращаться с помощью изменяемых операций, таких как operator= или reset, одновременно из нескольких потоков, даже если эти экземпляры являются копиями и внутренне делят один и тот же блок управления.

Тип T может быть неполным типом.

Типы членов

Тип члена Определение
value_type std::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> значением null.
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) Сбрасывает атомарный указатель на shared pointer к значению null. Эквивалентно store(nullptr);.

atomic<shared_ptr<T>>::is_lock_free

bool is_lock_free() const noexcept;

Возвращает 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

std::shared_ptr<T> load( std::memory_order order = std::memory_order_seq_cst ) const noexcept;

Атомарно возвращает копию базового shared pointer. Порядок памяти соответствует 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>() const noexcept;

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

atomic<shared_ptr<T>>::notify_one

void notify_one() noexcept;

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

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

END_OF_DOCUMENT_MARKER

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

static constexpr bool is_always_lock_free = /*implementation-defined*/;

Примечания

Макрос проверки наличия функции Значение Std Функция
__cpp_lib_atomic_shared_ptr 201711L (C++20) std::atomic<std::shared_ptr>

Пример

Отчеты об ошибках

Следующие отчеты об ошибках, изменяющих поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применимо к Поведение, как опубликовано Правильное поведение
LWG 3661 C++20 atomic<shared_ptr<T>> не допускалось постоянное инициализацию из nullptr сделано допускающим постоянную инициализацию
LWG 3893 C++20 LWG3661 сделал atomic<shared_ptr<T>> не допускающим присваивание из nullptr_t восстановлена возможность присваивания

См. также

atomic
(C++11)
Шаблон класса atomic и его специализации для bool, целых, с плавающей точкой,(с C++20) и указателей
(шаблон класса)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic2

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API