D.3.8. Шаблон класса std::atomic
Шаблон класса std::atomic является оберткой, позволяющей строить атомарные операции для любого типа, удовлетворяющего следующим условиям.
Параметр шаблона BaseТуре должен:
• иметь тривиальный конструктор по умолчанию;
• иметь тривиальный копирующий оператор присваивания;
• иметь тривиальный деструктор;
• допускать побитовое сравнение на равенство.
По существу, это означает, что конкретизация std::atomic<некоторый-встроенный-тип> допустима, как и конкретизация std::atomic<некоторая-простая-структура>, но такие вещи, как std::atomic<std::string>, недопустимы.
Помимо основного шаблона, имеются специализации для встроенных целочисленных типов и указателей, которые предоставляют дополнительные операции, например x++.
Экземпляры std::atomic не удовлетворяют требованиям концепций CopyConstructible и CopyAssignable, потому что такие операции невозможно выполнить атомарно.
Определение класса
template<typename BaseType>
struct atomic {
atomic() noexcept = default;
constexpr atomic(BaseType) noexcept;
BaseType operator=(BaseType) volatile noexcept;
BaseType operator=(BaseType) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
void store(BaseType, memory_order = memory_order_seq_cst)
volatile noexcept;
void store(BaseType, memory_order = memory_order_seq_cst)
noexcept;
BaseType load(memory_order = memory_order_seq_cst)
const volatile noexcept;
BaseType load(memory_order = memory_order_seq_cst)
const noexcept;
BaseType exchange(BaseType, memory_order = memory_order_seq_cst)
volatile noexcept;
BaseType exchange(BaseType, memory_order = memory_order_seq_cst)
noexcept;
bool compare_exchange_strong(
BaseType & old_value, BaseType new_value,
memory_order order = memory_order_seq_cst) volatile noexcept;
bool compare_exchange_strong(
BaseType & old_value, BaseType new_value,
memory_order order = memory_order_seq_cst) noexcept;
bool compare_exchange_strong(
BaseType & old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) volatile noexcept;
bool compare_exchange_strong(
BaseType & old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
bool compare_exchange_weak(
BaseType & old_value, BaseType new_value,
memory_order order = memory_order_seq_cst)
volatile noexcept;
bool compare_exchange_weak(
BaseType & old_value, BaseType new_value,
memory_order order = memory_order_seq_cst) noexcept;
bool compare_exchange_weak(
BaseType & old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) volatile noexcept;
bool compare_exchange_weak(
BaseType & old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
operator BaseType() const volatile noexcept;
operator BaseType() const noexcept;
};
template<typename BaseType>
bool atomic_is_lock_free(
volatile const atomic<BaseType>*) noexcept;
template<typename BaseType>
bool atomic_is_lock_free(const atomic<BaseType>*)
noexcept;
template<typename BaseType>
void atomic_init(volatile atomic<BaseType>*, void*) noexcept;
template<typename BaseType>
void atomic_init(atomic<BaseType>*, void*) noexcept;
template<typename BaseType>
BaseType atomic_exchange(
volatile atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_exchange(
atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_exchange_explicit(
volatile atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_exchange_explicit(
atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
void atomic_store(volatile atomic<BaseType>*, BaseType) noexcept;
template<typename BaseType>
void atomic_store(atomic<BaseType>*, BaseType) noexcept;
template<typename BaseType>
void atomic_store_explicit(
volatile atomic<BaseType>*, BaseType, memory_order) noexcept;
template<typename BaseType>
void atomic_store_explicit(
atomic<BaseType>*, BaseType, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_load(volatile const atomic<BaseType>*) noexcept;
template<typename BaseType>
BaseType atomic_load(const atomic<BaseType>*) noexcept;
template<typename BaseType>
BaseType atomic_load_explicit(
volatile const atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_load_explicit(
const atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong(
volatile atomic<BaseType>*,
BaseType * old_value, BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong(
atomic<BaseType>*,
BaseType * old_value, BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong_explicit(
volatile atomic<BaseType>*, BaseType * old_value,
BaseType new_value, memory_order success_order,
memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong_explicit(
atomic<BaseType>*,
BaseType * old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak(
volatile atomic<BaseType>*,
BaseType * old_value, BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak(
atomic<BaseType>*,
BaseType * old_value, BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak_explicit(
volatile atomic<BaseType>*,
BaseType * old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak_explicit(
atomic<BaseType>*,
BaseType * old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
Примечание. Хотя функции, не являющиеся членами класса, определены как шаблоны, они могут быть предоставлены в виде набора перегруженных функций, поэтому задавать явную спецификацию аргументов шаблона не следует.
STD::ATOMIC , КОНСТРУКТОР ПО УМОЛЧАНИЮ
Конструирует экземпляр std::atomic со значением, инициализированным по умолчанию.
Объявление
atomic() noexcept;
Результат
Конструирует новый объект std::atomic со значением, инициализированным по умолчанию. Для объектов со статическим временем жизни обеспечивается статическая инициализация.
Примечание. Если время жизни объекта std::atomic не статическое, то значение, которое будет иметь объект, инициализированный конструктором по умолчанию, непредсказуемо.
Исключения
Нет.
STD::ATOMIC_INIT , ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Неатомарно сохраняет указанное значение в объекте типа std::atomic<BaseType>.
Объявление
template<typename BaseType>
void atomic_init(
atomic<BaseType> volatile* p, BaseType v) noexcept;
template<typename BaseType>
void atomic_init(atomic<BaseType>* p, BaseType v) noexcept;
Результат
Неатомарно сохраняет значение v в *p. Вызов atomic_init() с передачей в качестве аргумента объекта atomic<BaseType>, который не был сконструирован по умолчанию или над которым производились какие-нибудь операции после конструирования, является неопределенным поведением.
Примечание. Поскольку эта операция сохранения неатомарна, то одновременный доступ к объекту, на который указывает p, из другого потока (даже с помощью атомарной операции) представляет собой гонку за данными.
Исключения
Нет.
STD::ATOMIC , КОНВЕРТИРУЮЩИЙ КОНСТРУКТОР
Конструирует экземпляр std::atomic из переданного значения типа BaseType.
Объявление
constexpr atomic(BaseType b) noexcept;
Результат
Конструирует новый объект std::atomic из значения b. Для объектов со статическим временем жизни обеспечивается статическая инициализация.
Исключения
Нет.
STD::ATOMIC , КОНВЕРТИРУЮЩИЙ ОПЕРАТОР ПРИСВАИВАНИЯ
Сохраняет новое значение в *this.
Объявление
BaseType operator=(BaseType b) volatile noexcept;
BaseType operator=(BaseType b) noexcept;
Результат
return this->store(b);
STD::ATOMIC::IS_LOCK_FREE , ФУНКЦИЯ-ЧЛЕН
Сообщает, являются ли операции над *this свободными от блокировок.
Объявление
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
Возвращаемое значение
true, если операции над *this свободны от блокировок, иначе false.
Исключения
Нет.
STD::ATOMIC_IS_LOCK_FREE , ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Сообщает, являются ли операции над *this свободными от блокировок.
Объявление
template<typename BaseType>
bool atomic_is_lock_free(
volatile const atomic<BaseType>* p) noexcept;
template<typename BaseType>
bool atomic_is_lock_free(const atomic<BaseType>* p) noexcept;
Результат
return p->is_lock_free();
STD::ATOMIC::LOAD , ФУНКЦИЯ-ЧЛЕН
Атомарно загружает текущее значение объекта std::atomic.
Объявление
BaseType load(memory_order order = memory_order_seq_cst)
const volatile noexcept;
BaseType load(
memory_order order = memory_order_seq_cst) const noexcept;
Предусловия
Параметр order должен принимать одно из значений std::memory_order_relaxed, std::memory_order_acquire, std: :memory_order_consume или std::memory_order_seq_cst.
Результат
Атомарно загружает текущее, хранящееся в *this.
Возвращаемое значение
Значение, хранящееся в *this, в точке вызова.
Исключения
Нет.
Примечание. Это атомарная операция загрузки для ячейки памяти, содержащей *this.
STD::ATOMIC_LOAD , ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно загружает текущее значение объекта std::atomic.
Объявление
template<typename BaseType>
BaseType atomic_load(volatile const atomic<BaseType>* p) noexcept;
template<typename BaseType>
BaseType atomic_load(const atomic<BaseType>* p) noexcept;
Результат
return p->load();
STD::ATOMIC_LOAD_EXPLICIT , ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно загружает текущее значение объекта std::atomic.
Объявление
template<typename BaseType>
BaseType atomic_load_explicit(
volatile const atomic<BaseType>* p,
memory_order order) noexcept;
template<typename BaseType>
BaseType atomic_load_explicit(
const atomic<BaseType>* p, memory_order order) noexcept;
Результат
return p->load(order);
STD::ATOMIC::OPERATOR , ОПЕРАТОР ПРЕОБРАЗОВАНИЯ В ТИП BASETYPE
Загружает значение, хранящееся в *this.
Объявление
operator BaseType() const volatile noexcept;
operator BaseType() const noexcept;
Результат
return this->load();
STD::ATOMIC::STORE , ФУНКЦИЯ-ЧЛЕН
Атомарно сохраняет новое значение в объекте atomic<BaseType>.
Объявление
void store(
BaseType new_value, memory_order order = memory_order_seq_cst)
volatile noexcept;
void store(
BaseType new_value, memory_order order = memory_order_seq_cst)
noexcept;
Предусловия
Параметр order должен принимать одно из значений std::memory_order_relaxed, std::memory_order_release или std::memory_order_seq_cst.
Результат
Атомарно сохраняет значение new_value в *this.
Исключения
Нет.
Примечание. Это атомарная операция сохранения для ячейки памяти, содержащей *this.
STD::ATOMIC_STORE , ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно сохраняет новое значение в объекте atomic<BaseType>.
Объявление
template<typename BaseType>
void atomic_store(
volatile atomic<BaseType>* p, BaseType new_value) noexcept;
template<typename BaseType>
void atomic_store(
atomic<BaseType>* p, BaseType new_value) noexcept;
Результат
p->store(new_value);
STD::ATOMIC_STORE_EXPLICIT , ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно сохраняет новое значение в объекте atomic<BaseType>.
Объявление
template<typename BaseType>
void atomic_store_explicit(
volatile atomic<BaseType>* p, BaseType new_value,
memory_order order) noexcept;
template<typename BaseType>
void atomic_store_explicit(
atomic<BaseType>* p, BaseType new_value,
memory_order order) noexcept;
Результат
p->store(new_value, order);
STD::ATOMIC::EXCHANGE , ФУНКЦИЯ-ЧЛЕН
Атомарно сохраняет новое значение и читает старое.
Объявление
BaseType exchange(
BaseType new_value,
memory_order order = memory_order_seq_cst) volatile noexcept;
Результат
Атомарно сохраняет значение new_value в *this и извлекает прежнее значение *this.
Возвращаемое значение
Значение *this непосредственно перед сохранением.
Исключения
Нет.
Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей *this.
STD::ATOMIC_EXCHANGE , ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно сохраняет новое значение в объекте atomic<BaseType> и читает предыдущее значение.
Объявление
template<typename BaseType>
BaseType atomic_exchange(
volatile atomic<BaseType>* p, BaseType new_value) noexcept;
template<typename BaseType>
BaseType atomic_exchange(
atomic<BaseType>* p, BaseType new_value) noexcept;
Результат
return p->exchange(new_value);
STD::ATOMIC_EXCHANGE_EXPLICIT , ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно сохраняет новое значение в объекте atomic<BaseType> и читает предыдущее значение.
Объявление
template<typename BaseType>
BaseType atomic_exchange_explicit(
volatile atomic<BaseType>* p,
BaseType new_value, memory_order order)
noexcept;
template<typename BaseType>
BaseType atomic_exchange_explicit(
atomic<BaseType>* p,
BaseType new_value, memory_order order) noexcept;
Результат
return p->exchange(new_value, order);
STD::ATOMIC::COMPARE_EXCHANGE_STRONG , ФУНКЦИЯ-ЧЛЕН
Атомарно сравнивает значение с ожидаемым и, если они равны, сохраняет новое значение. Если значения не равны, то заменяет ожидаемое значение прочитанным.
Объявление
bool compare_exchange_strong(
BaseType& expected, BaseType new_value,
memory_order order = std::memory_order_seq_cst)
volatile noexcept;
bool compare_exchange_strong(
BaseType& expected, BaseType new_value,
memory_order order = std::memory_order_seq_cst) noexcept;
bool compare_exchange_strong(
BaseType& expected, BaseType new_value,
memory_order success_order, memory_order failure_order)
volatile noexcept;
bool compare_exchange_strong(
BaseType& expected, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
Предусловия
Параметр failure_order не должен быть равен std::memory_order_release или std::memory_order_acq_rel.
Результат
Атомарно сравнивает expected со значением, хранящимся в *this, применяя побитовое сравнение, и сохраняет new_value в *this, если значения равны. В противном случае записывает в expected прочитанное значение.
Возвращаемое значение
true, если значение, хранящееся в *this, совпало с expected. В противном случае false.
Исключения
Нет.
Примечание. Этот перегруженный вариант функции с тремя параметрами эквивалентен перегруженному варианту с четырьмя параметрами, где success_order == order и failure_order == order, с тем отличием, что если order равно std::memory_order_acq_rel, то failure_order равно std::memory_order_acquire, а если order равно std::memory_order_release, то failure_order равно std::memory_order_relaxed.
Примечание. Если результат равен true, то это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей *this, с упорядочением доступа к памяти success_order; в противном случае это атомарная операция загрузки для ячейки памяти, содержащей *this, с упорядочением доступа к памяти failure_order.
STD::ATOMIC_COMPARE_EXCHANGE_STRONG , ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно сравнивает значение с ожидаемым и, если они равны, сохраняет новое значение. Если значения не равны, то заменяет ожидаемое значение прочитанным.
Объявление
template<typename BaseType>
bool atomic_compare_exchange_strong(
volatile atomic<BaseType>* p,
BaseType * old_value, BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong(
atomic<BaseType>* p,
BaseType * old_value, BaseType new_value) noexcept;
Результат
return p->compare_exchange_strong(*old_value, new_value);
STD::ATOMIC_COMPARE_EXCHANGE_STRONG_EXPLICIT , ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно сравнивает значение с ожидаемым и, если они равны, сохраняет новое значение. Если значения не равны, то заменяет ожидаемое значение прочитанным.
Объявление
template<typename BaseType>
bool atomic_compare_exchange_strong_explicit(
volatile atomic<BaseType>* p,
BaseType * old_value, BaseType new_value,
memory_order success_order, memory_order failure_order)
noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong_explicit(
atomic<BaseType>* p,
BaseType * old_value, BaseType new_value,
memory_order success_order, memory_order failure_order)
noexcept;
Результат
return p->compare_exchange_strong(
*old_value, new_value, success_order, failure_order) noexcept;
STD::ATOMIC::COMPARE_EXCHANGE_WEAK , ФУНКЦИЯ-ЧЛЕН
Атомарно сравнивает значение с ожидаемым и, если они равны и обновление может быть произведено атомарно, то сохраняет новое значение. Если значения не равны или обновление не может быть произведено атомарно, то заменяет ожидаемое значение прочитанным.
Объявление
bool compare_exchange_weak(
BaseType& expected, BaseType new_value,
memory_order order = std::memory_order_seq_cst)
volatile noexcept;
bool compare_exchange_weak(
BaseType& expected, BaseType new_value,
memory_order order = std::memory_order_seq_cst) noexcept;
bool compare_exchange_weak(
BaseType& expected, BaseType new_value,
memory_order success_order, memory_order failure_order)
volatile noexcept;
bool compare_exchange_weak(
BaseType& expected, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
Предусловия
Параметр failure_order не должен быть равен std::memory_order_release или std::memory_order_acq_rel.
Результат
Атомарно сравнивает expected со значением, хранящимся в *this, применяя побитовое сравнение, и сохраняет new_value в *this, если значения равны. Если значения не равны или обновление не может быть произведено атомарно, записывает в expected прочитанное значение.
Возвращаемое значение
true, если значение, хранящееся в *this, совпало с expected и new_value успешно сохранено в *this. В противном случае false.
Исключения
Нет.
Примечание. Этот перегруженный вариант функции с тремя параметрами эквивалентен перегруженному варианту с четырьмя параметрами, где success_order == order и failure_order == order, с тем отличием, что если order равно std::memory_order_acq_rel, то failure_order равно std::memory_order_acquire, а если order равно std::memory_order_release, то failure_order равно std::memory_order_relaxed.
Примечание. Если результат равен true, то это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей *this, с упорядочением доступа к памяти success_order; в противном случае это атомарная операция загрузки для ячейки памяти, содержащей *this, с упорядочением доступа к памяти failure_order.
STD::ATOMIC_COMPARE_EXCHANGE_WEAK , ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно сравнивает значение с ожидаемым и, если они равны и обновление может быть произведено атомарно, то сохраняет новое значение. Если значения не равны или обновление не может быть произведено атомарно, то заменяет ожидаемое значение прочитанным.
Объявление
template<typename BaseType>
bool atomic_compare_exchange_weak(
volatile atomic<BaseType>* p,
BaseType * old_value, BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak(
atomic<BaseType>* p,
BaseType * old_value, BaseType new_value) noexcept;
Результат
return p->compare_exchange_weak(*old_value, new_value);
STD::ATOMIC_COMPARE_EXCHANGE_WEAK_EXPLICIT , ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА
Атомарно сравнивает значение с ожидаемым и, если они равны и обновление может быть произведено атомарно, то сохраняет новое значение. Если значения не равны или обновление не может быть произведено атомарно, то заменяет ожидаемое значение прочитанным.
template<typename BaseType>
bool atomic_compare_exchange_weak_explicit(
volatile atomic<BaseType>* p,
BaseType * old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak_explicit(
atomic<BaseType>* p,
BaseType * old_value, BaseType new_value,
memory_order success_order,
memory_order failure_order) noexcept;
Результат
return p->compare_exchange_weak(
*old_value, new_value, success_order, failure_order);