D.3 <atomic>头文件 - C++并发编程

返回介绍

D.3 <atomic>头文件

发布于 2019-06-11 字数 69180 浏览 1027 评论 0

<atomic>头文件提供一组基础的原子类型,和提供对这些基本类型的操作,以及一个原子模板函数,用来接收用户定义的类型,以适用于某些标准。

头文件内容

#define ATOMIC_BOOL_LOCK_FREE 参见详述
#define ATOMIC_CHAR_LOCK_FREE 参见详述
#define ATOMIC_SHORT_LOCK_FREE 参见详述
#define ATOMIC_INT_LOCK_FREE 参见详述
#define ATOMIC_LONG_LOCK_FREE 参见详述
#define ATOMIC_LLONG_LOCK_FREE 参见详述
#define ATOMIC_CHAR16_T_LOCK_FREE 参见详述
#define ATOMIC_CHAR32_T_LOCK_FREE 参见详述
#define ATOMIC_WCHAR_T_LOCK_FREE 参见详述
#define ATOMIC_POINTER_LOCK_FREE 参见详述

#define ATOMIC_VAR_INIT(value) 参见详述

namespace std
{
  enum memory_order;

  struct atomic_flag;
  参见类型定义详述 atomic_bool;
  参见类型定义详述 atomic_char;
  参见类型定义详述 atomic_char16_t;
  参见类型定义详述 atomic_char32_t;
  参见类型定义详述 atomic_schar;
  参见类型定义详述 atomic_uchar;
  参见类型定义详述 atomic_short;
  参见类型定义详述 atomic_ushort;
  参见类型定义详述 atomic_int;
  参见类型定义详述 atomic_uint;
  参见类型定义详述 atomic_long;
  参见类型定义详述 atomic_ulong;
  参见类型定义详述 atomic_llong;
  参见类型定义详述 atomic_ullong;
  参见类型定义详述 atomic_wchar_t;

  参见类型定义详述 atomic_int_least8_t;
  参见类型定义详述 atomic_uint_least8_t;
  参见类型定义详述 atomic_int_least16_t;
  参见类型定义详述 atomic_uint_least16_t;
  参见类型定义详述 atomic_int_least32_t;
  参见类型定义详述 atomic_uint_least32_t;
  参见类型定义详述 atomic_int_least64_t;
  参见类型定义详述 atomic_uint_least64_t;
  参见类型定义详述 atomic_int_fast8_t;
  参见类型定义详述 atomic_uint_fast8_t;
  参见类型定义详述 atomic_int_fast16_t;
  参见类型定义详述 atomic_uint_fast16_t;
  参见类型定义详述 atomic_int_fast32_t;
  参见类型定义详述 atomic_uint_fast32_t;
  参见类型定义详述 atomic_int_fast64_t;
  参见类型定义详述 atomic_uint_fast64_t;
  参见类型定义详述 atomic_int8_t;
  参见类型定义详述 atomic_uint8_t;
  参见类型定义详述 atomic_int16_t;
  参见类型定义详述 atomic_uint16_t;
  参见类型定义详述 atomic_int32_t;
  参见类型定义详述 atomic_uint32_t;
  参见类型定义详述 atomic_int64_t;
  参见类型定义详述 atomic_uint64_t;
  参见类型定义详述 atomic_intptr_t;
  参见类型定义详述 atomic_uintptr_t;
  参见类型定义详述 atomic_size_t;
  参见类型定义详述 atomic_ssize_t;
  参见类型定义详述 atomic_ptrdiff_t;
  参见类型定义详述 atomic_intmax_t;
  参见类型定义详述 atomic_uintmax_t;

  template<typename T>
  struct atomic;

  extern "C" void atomic_thread_fence(memory_order order);
  extern "C" void atomic_signal_fence(memory_order order);

  template<typename T>
  T kill_dependency(T);
}

std::atomic_xxx类型定义

为了兼容新的C标准(C11),C++支持定义原子整型类型。这些类型都与std::atimic<T>;特化类相对应,或是用同一接口特化的一个基本类型。

Table D.1 原子类型定义和与之相关的std::atmoic<>特化模板

std::atomic_itype 原子类型 std::atomic<> 相关特化类
atomic_char std::atomic<char>
atomic_schar std::atomic<signed char>
atomic_uchar std::atomic<unsigned char>
atomic_int std::atomic<int>
atomic_uint std::atomic<unsigned>
atomic_short std::atomic<short>
atomic_ushort std::atomic<unsigned short>
atomic_long std::atomic<long>
atomic_ulong std::atomic<unsigned long>
atomic_llong std::atomic<long long>
atomic_ullong std::atomic<unsigned long long>
atomic_wchar_t std::atomic<wchar_t>
atomic_char16_t std::atomic<char16_t>
atomic_char32_t std::atomic<char32_t>

(译者注:该表与第5章中的表5.1几乎一致)

D.3.2 ATOMIC_xxx_LOCK_FREE宏

这里的宏指定了原子类型与其内置类型是否是无锁的。

宏定义

#define ATOMIC_BOOL_LOCK_FREE 参见详述
#define ATOMIC_CHAR_LOCK_FREE参见详述
#define ATOMIC_SHORT_LOCK_FREE 参见详述
#define ATOMIC_INT_LOCK_FREE 参见详述
#define ATOMIC_LONG_LOCK_FREE 参见详述
#define ATOMIC_LLONG_LOCK_FREE 参见详述
#define ATOMIC_CHAR16_T_LOCK_FREE 参见详述
#define ATOMIC_CHAR32_T_LOCK_FREE 参见详述
#define ATOMIC_WCHAR_T_LOCK_FREE 参见详述
#define ATOMIC_POINTER_LOCK_FREE 参见详述

ATOMIC_xxx_LOCK_FREE的值无非就是0,1,2。0意味着,在对有无符号的相关原子类型操作是有锁的;1意味着,操作只对一些特定的类型上锁,而对没有指定的类型不上锁;2意味着,所有操作都是无锁的。例如,当ATOMIC_INT_LOCK_FREE是2的时候,在std::atomic&lt;int&gt;std::atomic&lt;unsigned&gt;上的操作始终无锁。

ATOMIC_POINTER_LOCK_FREE描述了,对于特化的原子类型指针std::atomic<T*>操作的无锁特性。

D.3.3 ATOMIC_VAR_INIT宏

ATOMIC_VAR_INIT宏可以通过一个特定的值来初始化一个原子变量。

声明
#define ATOMIC_VAR_INIT(value)参见详述

宏可以扩展成一系列符号,这个宏可以通过一个给定值,初始化一个标准原子类型,表达式如下所示:

std::atomic<type> x = ATOMIC_VAR_INIT(val);

给定值可以兼容与原子变量相关的非原子变量,例如:

std::atomic&lt;int> i = ATOMIC_VAR_INIT(42);
std::string s;
std::atomic&lt;std::string*> p = ATOMIC_VAR_INIT(&s);

这样初始化的变量是非原子的,并且在变量初始化之后,其他线程可以随意的访问该变量,这样可以避免条件竞争和未定义行为的发生。

D.3.4 std::memory_order枚举类型

std::memory_order枚举类型用来表明原子操作的约束顺序。

声明

typedef enum memory_order
{
  memory_order_relaxed,memory_order_consume,
  memory_order_acquire,memory_order_release,
  memory_order_acq_rel,memory_order_seq_cst
} memory_order;

通过标记各种内存序变量来标记操作的顺序(详见第5章,在该章节中有对书序约束更加详尽的介绍)

std::memory_order_relaxed

操作不受任何额外的限制。

std::memory_order_release

对于指定位置上的内存可进行释放操作。因此,与获取操作读取同一内存位置所存储的值。

std::memory_order_acquire

操作可以获取指定内存位置上的值。当需要存储的值通过释放操作写入时,是与存储操同步的。

std::memory_order_acq_rel

操作必须是“读-改-写”操作,并且其行为需要在std::memory_order_acquirestd::memory_order_release序指定的内存位置上进行操作。

std::memory_order_seq_cst

操作在全局序上都会受到约束。还有,当为存储操作时,其行为好比std::memory_order_release操作;当为加载操作时,其行为好比std::memory_order_acquire操作;并且,当其是一个“读-改-写”操作时,其行为和std::memory_order_acquirestd::memory_order_release类似。对于所有顺序来说,该顺序为默认序。

std::memory_order_consume

对于指定位置的内存进行消耗操作(consume operation)。

(译者注:与memory_order_acquire类似)

D.3.5 std::atomic_thread_fence函数

std::atomic_thread_fence()会在代码中插入“内存栅栏”,强制两个操作保持内存约束顺序。

声明

extern "C" void atomic_thread_fence(std::memory_order order);

效果
插入栅栏的目的是为了保证内存序的约束性。

栅栏使用std::memory_order_release, std::memory_order_acq_rel, 或 std::memory_order_seq_cst内存序,会同步与一些内存位置上的获取操作进行同步,如果这些获取操作要获取一个已存储的值(通过原子操作进行的存储),就会通过栅栏进行同步。

释放操作可对std::memory_order_acquire, std::memory_order_acq_rel, 或 std::memory_order_seq_cst进行栅栏同步,;当释放操作存储的值,在一个原子操作之前读取,那么就会通过栅栏进行同步。

抛出

D.3.6 std::atomic_signal_fence函数

std::atomic_signal_fence()会在代码中插入“内存栅栏”,强制两个操作保持内存约束顺序,并且在对应线程上执行信号处理操作。

声明

extern "C" void atomic_signal_fence(std::memory_order order);

效果
根据需要的内存约束序插入一个栅栏。除非约束序应用于“操作和信号处理函数在同一线程”的情况下,否则,这个操作等价于std::atomic_thread_fence(order)操作。

抛出

D.3.7 std::atomic_flag类

std::atomic_flag类算是原子标识的骨架。在C++11标准下,只有这个数据类型可以保证是无锁的(当然,更多的原子类型在未来的实现中将采取无锁实现)。

对于一个std::atomic_flag来说,其状态不是set,就是clear。

类型定义

struct atomic_flag
{
  atomic_flag() noexcept = default;
  atomic_flag(const atomic_flag&) = delete;
  atomic_flag& operator=(const atomic_flag&) = delete;
  atomic_flag& operator=(const atomic_flag&) volatile = delete;

  bool test_and_set(memory_order = memory_order_seq_cst) volatile
    noexcept;
  bool test_and_set(memory_order = memory_order_seq_cst) noexcept;
  void clear(memory_order = memory_order_seq_cst) volatile noexcept;
  void clear(memory_order = memory_order_seq_cst) noexcept;
};

bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept;
bool atomic_flag_test_and_set(atomic_flag*) noexcept;
bool atomic_flag_test_and_set_explicit(
  volatile atomic_flag*, memory_order) noexcept;
bool atomic_flag_test_and_set_explicit(
  atomic_flag*, memory_order) noexcept;
void atomic_flag_clear(volatile atomic_flag*) noexcept;
void atomic_flag_clear(atomic_flag*) noexcept;
void atomic_flag_clear_explicit(
  volatile atomic_flag*, memory_order) noexcept;
void atomic_flag_clear_explicit(
  atomic_flag*, memory_order) noexcept;

#define ATOMIC_FLAG_INIT unspecified

std::atomic_flag 默认构造函数

这里未指定默认构造出来的std::atomic_flag实例是clear状态,还是set状态。因为对象存储过程是静态的,所以初始化必须是静态的。

声明

std::atomic_flag() noexcept = default;

效果
构造一个新std::atomic_flag对象,不过未指明状态。(薛定谔的猫?)

抛出

std::atomic_flag 使用ATOMIC_FLAG_INIT进行初始化

std::atomic_flag实例可以使用ATOMIC_FLAG_INIT宏进行创建,这样构造出来的实例状态为clear。因为对象存储过程是静态的,所以初始化必须是静态的。

声明

#define ATOMIC_FLAG_INIT unspecified

用法

std::atomic_flag flag=ATOMIC_FLAG_INIT;

效果
构造一个新std::atomic_flag对象,状态为clear。

抛出

NOTE
对于内存位置上的*this,这个操作属于“读-改-写”操作。

std::atomic_flag::test_and_set 成员函数

自动设置实例状态标识,并且检查实例的状态标识是否已经设置。

声明

bool atomic_flag_test_and_set(volatile atomic_flag* flag) noexcept;
bool atomic_flag_test_and_set(atomic_flag* flag) noexcept;

效果

return flag->test_and_set();

std::atomic_flag_test_and_set 非成员函数

自动设置原子变量的状态标识,并且检查原子变量的状态标识是否已经设置。

声明

bool atomic_flag_test_and_set_explicit(
    volatile atomic_flag* flag, memory_order order) noexcept;
bool atomic_flag_test_and_set_explicit(
    atomic_flag* flag, memory_order order) noexcept;

效果

return flag->test_and_set(order);

std::atomic_flag_test_and_set_explicit 非成员函数

自动设置原子变量的状态标识,并且检查原子变量的状态标识是否已经设置。

声明

bool atomic_flag_test_and_set_explicit(
    volatile atomic_flag* flag, memory_order order) noexcept;
bool atomic_flag_test_and_set_explicit(
    atomic_flag* flag, memory_order order) noexcept;

效果

return flag->test_and_set(order);

std::atomic_flag::clear 成员函数

自动清除原子变量的状态标识。

声明

void clear(memory_order order = memory_order_seq_cst) volatile noexcept;
void clear(memory_order order = memory_order_seq_cst) noexcept;

先决条件
支持std::memory_order_relaxed,std::memory_order_releasestd::memory_order_seq_cst中任意一个。

效果
自动清除变量状态标识。

抛出

NOTE:对于内存位置上的*this,这个操作属于“写”操作(存储操作)。

std::atomic_flag_clear 非成员函数

自动清除原子变量的状态标识。

声明

void atomic_flag_clear(volatile atomic_flag* flag) noexcept;
void atomic_flag_clear(atomic_flag* flag) noexcept;

效果

flag->clear();

std::atomic_flag_clear_explicit 非成员函数

自动清除原子变量的状态标识。

声明

void atomic_flag_clear_explicit(
    volatile atomic_flag* flag, memory_order order) noexcept;
void atomic_flag_clear_explicit(
    atomic_flag* flag, memory_order order) noexcept;

效果

return flag->clear(order);

D.3.8 std::atomic类型模板

std::atomic提供了对任意类型的原子操作的包装,以满足下面的需求。

模板参数BaseType必须满足下面的条件。

  • 具有简单的默认构造函数
  • 具有简单的拷贝赋值操作
  • 具有简单的析构函数
  • 可以进行位比较

这就意味着std::atomic&lt;some-simple-struct&gt;会和使用std::atomic<some-built-in-type>一样简单;不过对于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;

NOTE:虽然非成员函数通过模板的方式指定,不过他们只作为从在函数提供,并且对于这些函数,不能显示的指定模板的参数。

std::atomic 构造函数

使用默认初始值,构造一个std::atomic实例。

声明

atomic() noexcept;

效果
使用默认初始值,构造一个新std::atomic实例。因对象是静态存储的,所以初始化过程也是静态的。

NOTE:当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<BaseType>实例中的atomic_init(),这里需要实例不是默认构造出来的,或者在构造出来的时候被执行了某些操作,否则将会引发未定义行为。

NOTE:因为存储是非原子的,对对象指针p任意的并发访问(即使是原子操作)都会引发数据竞争。

抛出

std::atomic 转换构造函数

使用提供的BaseType值去构造一个std::atomic实例。

声明

constexpr atomic(BaseType b) noexcept;

效果
通过b值构造一个新的std::atomic对象。因对象是静态存储的,所以初始化过程也是静态的。

抛出

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,否则返回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;

先决条件
支持std::memory_order_relaxedstd::memory_order_acquirestd::memory_order_consumestd::memory_order_seq_cst内存序。

效果
原子的加载已存储到*this上的值。

返回
返回存储在*this上的值。

抛出

NOTE:是对于*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 非成员函数

原子的加载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 BastType转换操作

加载存储在*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;

先决条件
支持std::memory_order_relaxedstd::memory_order_releasestd::memory_order_seq_cst内存序。

效果
将new_value原子的存储到*this中。

抛出

NOTE:是对于*this内存地址原子加载的操作。

std::atomic_store 非成员函数

以原子操作的方式存储一个新值到atomic&lt;BaseType&gt;实例中。

声明

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_explicit 非成员函数

以原子操作的方式存储一个新值到atomic&lt;BaseType&gt;实例中。

声明

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之前的值。

抛出

NOTE:这是对*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 非成员函数

原子的存储一个新值到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_releasestd::memory_order_acq_rel内存序。

效果
将存储在this中的expected值与new_value值进行逐位对比,当相等时间new_value存储在this中;否则,更新expected的值。

返回
当new_value的值与*this中已经存在的值相同,就返回true;否则,返回false。

抛出

NOTE:在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

NOTE:当返回true和success_order内存序时,是对this内存地址的原子“读-改-写”操作;反之,这是对this内存地址的原子加载操作(failure_order)。

std::atomic_compare_exchange_strong 非成员函数

当期望值和新值一样时,将新值存储到实例中。如果不相等,那么就实用新值更新期望值。

声明

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 非成员函数

当期望值和新值一样时,将新值存储到实例中。如果不相等,那么就实用新值更新期望值。

声明

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_releasestd::memory_order_acq_rel内存序。

效果
将存储在this中的expected值与new_value值进行逐位对比,当相等时间new_value存储在this中;否则,更新expected的值。

返回
当new_value的值与*this中已经存在的值相同,就返回true;否则,返回false。

抛出

NOTE:在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

NOTE:当返回true和success_order内存序时,是对this内存地址的原子“读-改-写”操作;反之,这是对this内存地址的原子加载操作(failure_order)。

std::atomic_compare_exchange_weak 非成员函数

原子的比较新值和期望值,如果相等,那么存储新值并且进行原子化更新。当两值不相等,或更新未进行,那期望值会更新为新值。

声明

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 非成员函数

原子的比较新值和期望值,如果相等,那么存储新值并且进行原子化更新。当两值不相等,或更新未进行,那期望值会更新为新值。

声明

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);

D.3.9 std::atomic模板类型的特化

std::atomic类模板的特化类型有整型和指针类型。对于整型来说,特化模板提供原子加减,以及位域操作(主模板未提供)。对于指针类型来说,特化模板提供原子指针的运算(主模板未提供)。

特化模板提供如下整型:

std::atomic<bool>
std::atomic<char>
std::atomic<signed char>
std::atomic<unsigned char>
std::atomic<short>
std::atomic<unsigned short>
std::atomic<int>
std::atomic<unsigned>
std::atomic<long>
std::atomic<unsigned long>
std::atomic<long long>
std::atomic<unsigned long long>
std::atomic<wchar_t>
std::atomic<char16_t>
std::atomic<char32_t&gt;

std::atomic<T*>原子指针,可以使用以上的类型作为T。

D.3.10 特化std::atomic<integral-type>

std::atomic&lt;integral-type&gt;是为每一个基础整型提供的std::atomic类模板,其中提供了一套完整的整型操作。

下面的特化模板也适用于std::atomic<>类模板:

std::atomic<char>
std::atomic<signed char>
std::atomic<unsigned char>
std::atomic<short>
std::atomic<unsigned short>
std::atomic<int>
std::atomic<unsigned>
std::atomic<long>
std::atomic<unsigned long>
std::atomic<long long>
std::atomic<unsigned long long>
std::atomic<wchar_t>
std::atomic<char16_t>
std::atomic<char32_t>

因为原子操作只能执行其中一个,所以特化模板的实例不可CopyConstructible(拷贝构造)和CopyAssignable(拷贝赋值)。

类型定义

template<>
struct atomic<integral-type>
{
  atomic() noexcept = default;
  constexpr atomic(integral-type) noexcept;
  bool operator=(integral-type) volatile 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(integral-type,memory_order = memory_order_seq_cst)
      volatile noexcept;
  void store(integral-type,memory_order = memory_order_seq_cst) noexcept;
  integral-type load(memory_order = memory_order_seq_cst)
      const volatile noexcept;
  integral-type load(memory_order = memory_order_seq_cst) const noexcept;
  integral-type exchange(
      integral-type,memory_order = memory_order_seq_cst)
      volatile noexcept;
 integral-type exchange(
      integral-type,memory_order = memory_order_seq_cst) noexcept;

  bool compare_exchange_strong(
      integral-type & old_value,integral-type new_value,
      memory_order order = memory_order_seq_cst) volatile noexcept;
  bool compare_exchange_strong(
      integral-type & old_value,integral-type new_value,
      memory_order order = memory_order_seq_cst) noexcept;
  bool compare_exchange_strong(
      integral-type & old_value,integral-type new_value,
      memory_order success_order,memory_order failure_order)
      volatile noexcept;
  bool compare_exchange_strong(
      integral-type & old_value,integral-type new_value,
      memory_order success_order,memory_order failure_order) noexcept;
  bool compare_exchange_weak(
      integral-type & old_value,integral-type new_value,
      memory_order order = memory_order_seq_cst) volatile noexcept;
  bool compare_exchange_weak(
      integral-type & old_value,integral-type new_value,
      memory_order order = memory_order_seq_cst) noexcept;
  bool compare_exchange_weak(
      integral-type & old_value,integral-type new_value,
      memory_order success_order,memory_order failure_order)
      volatile noexcept;
  bool compare_exchange_weak(
      integral-type & old_value,integral-type new_value,
      memory_order success_order,memory_order failure_order) noexcept;

  operator integral-type() const volatile noexcept;
  operator integral-type() const noexcept;

  integral-type fetch_add(
      integral-type,memory_order = memory_order_seq_cst)
      volatile noexcept;
  integral-type fetch_add(
      integral-type,memory_order = memory_order_seq_cst) noexcept;
  integral-type fetch_sub(
      integral-type,memory_order = memory_order_seq_cst)
      volatile noexcept;
  integral-type fetch_sub(
      integral-type,memory_order = memory_order_seq_cst) noexcept;
  integral-type fetch_and(
      integral-type,memory_order = memory_order_seq_cst)
      volatile noexcept;
  integral-type fetch_and(
      integral-type,memory_order = memory_order_seq_cst) noexcept;
  integral-type fetch_or(
      integral-type,memory_order = memory_order_seq_cst)
      volatile noexcept;
  integral-type fetch_or(
      integral-type,memory_order = memory_order_seq_cst) noexcept;
  integral-type fetch_xor(
      integral-type,memory_order = memory_order_seq_cst)
      volatile noexcept;
  integral-type fetch_xor(
      integral-type,memory_order = memory_order_seq_cst) noexcept;

  integral-type operator++() volatile noexcept;
  integral-type operator++() noexcept;
  integral-type operator++(int) volatile noexcept;
  integral-type operator++(int) noexcept;
  integral-type operator--() volatile noexcept;
  integral-type operator--() noexcept;
  integral-type operator--(int) volatile noexcept;
  integral-type operator--(int) noexcept;
  integral-type operator+=(integral-type) volatile noexcept;
  integral-type operator+=(integral-type) noexcept;
  integral-type operator-=(integral-type) volatile noexcept;
  integral-type operator-=(integral-type) noexcept;
  integral-type operator&=(integral-type) volatile noexcept;
  integral-type operator&=(integral-type) noexcept;
  integral-type operator|=(integral-type) volatile noexcept;
  integral-type operator|=(integral-type) noexcept;
  integral-type operator^=(integral-type) volatile noexcept;
  integral-type operator^=(integral-type) noexcept;
};

bool atomic_is_lock_free(volatile const atomic<integral-type>*) noexcept;
bool atomic_is_lock_free(const atomic<integral-type>*) noexcept;
void atomic_init(volatile atomic<integral-type>*,integral-type) noexcept;
void atomic_init(atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_exchange(
    volatile atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_exchange(
    atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_exchange_explicit(
    volatile atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_exchange_explicit(
    atomic<integral-type>*,integral-type, memory_order) noexcept;
void atomic_store(volatile atomic<integral-type>*,integral-type) noexcept;
void atomic_store(atomic<integral-type>*,integral-type) noexcept;
void atomic_store_explicit(
    volatile atomic<integral-type>*,integral-type, memory_order) noexcept;
void atomic_store_explicit(
    atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_load(volatile const atomic<integral-type>*) noexcept;
integral-type atomic_load(const atomic<integral-type>*) noexcept;
integral-type atomic_load_explicit(
    volatile const atomic<integral-type>*,memory_order) noexcept;
integral-type atomic_load_explicit(
    const atomic<integral-type>*,memory_order) noexcept;
bool atomic_compare_exchange_strong(
    volatile atomic<integral-type>*,
    integral-type * old_value,integral-type new_value) noexcept;
bool atomic_compare_exchange_strong(
    atomic<integral-type>*,
    integral-type * old_value,integral-type new_value) noexcept;
bool atomic_compare_exchange_strong_explicit(
    volatile atomic<integral-type>*,
    integral-type * old_value,integral-type new_value,
    memory_order success_order,memory_order failure_order) noexcept;
bool atomic_compare_exchange_strong_explicit(
    atomic<integral-type>*,
    integral-type * old_value,integral-type new_value,
    memory_order success_order,memory_order failure_order) noexcept;
bool atomic_compare_exchange_weak(
    volatile atomic<integral-type>*,
    integral-type * old_value,integral-type new_value) noexcept;
bool atomic_compare_exchange_weak(
    atomic<integral-type>*,
    integral-type * old_value,integral-type new_value) noexcept;
bool atomic_compare_exchange_weak_explicit(
    volatile atomic<integral-type>*,
    integral-type * old_value,integral-type new_value,
    memory_order success_order,memory_order failure_order) noexcept;
bool atomic_compare_exchange_weak_explicit(
    atomic<integral-type>*,
    integral-type * old_value,integral-type new_value,
    memory_order success_order,memory_order failure_order) noexcept;

integral-type atomic_fetch_add(
    volatile atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_add(
    atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_add_explicit(
    volatile atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_add_explicit(
    atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_sub(
    volatile atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_sub(
    atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_sub_explicit(
    volatile atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_sub_explicit(
    atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_and(
    volatile atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_and(
    atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_and_explicit(
    volatile atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_and_explicit(
    atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_or(
    volatile atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_or(
    atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_or_explicit(
    volatile atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_or_explicit(
    atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_xor(
    volatile atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_xor(
    atomic<integral-type>*,integral-type) noexcept;
integral-type atomic_fetch_xor_explicit(
    volatile atomic<integral-type>*,integral-type, memory_order) noexcept;
integral-type atomic_fetch_xor_explicit(
    atomic<integral-type>*,integral-type, memory_order) noexcept;

这些操作在主模板中也有提供(见D.3.8)。

std::atomic<integral-type>::fetch_add 成员函数

原子的加载一个值,然后使用与提供i相加的结果,替换掉原值。

声明

integral-type fetch_add(
    integral-type i,memory_order order = memory_order_seq_cst)
    volatile noexcept;
integral-type fetch_add(
    integral-type i,memory_order order = memory_order_seq_cst) noexcept;

效果
原子的查询this中的值,将old-value+i的和存回this。

返回
返回*this之前存储的值。

抛出

NOTE:对于*this的内存地址来说,这是一个“读-改-写”操作。

std::atomic_fetch_add 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值相加,替换原值。

声明

integral-type atomic_fetch_add(
    volatile atomic<integral-type>* p, integral-type i) noexcept;
integral-type atomic_fetch_add(
    atomic<integral-type>* p, integral-type i) noexcept;

效果

return p->fetch_add(i);

std::atomic_fetch_add_explicit 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值相加,替换原值。

声明

integral-type atomic_fetch_add_explicit(
    volatile atomic<integral-type>* p, integral-type i,
    memory_order order) noexcept;
integral-type atomic_fetch_add_explicit(
    atomic<integral-type>* p, integral-type i, memory_order order)
    noexcept;

效果

return p->fetch_add(i,order);

std::atomic<integral-type>::fetch_sub 成员函数

原子的加载一个值,然后使用与提供i相减的结果,替换掉原值。

声明

integral-type fetch_sub(
    integral-type i,memory_order order = memory_order_seq_cst)
    volatile noexcept;
integral-type fetch_sub(
    integral-type i,memory_order order = memory_order_seq_cst) noexcept;

效果
原子的查询this中的值,将old-value-i的和存回this。

返回
返回*this之前存储的值。

抛出

NOTE:对于*this的内存地址来说,这是一个“读-改-写”操作。

std::atomic_fetch_sub 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值相减,替换原值。

声明

integral-type atomic_fetch_sub(
    volatile atomic<integral-type>* p, integral-type i) noexcept;
integral-type atomic_fetch_sub(
    atomic<integral-type>* p, integral-type i) noexcept;

效果

return p->fetch_sub(i);

std::atomic_fetch_sub_explicit 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值相减,替换原值。

声明

integral-type atomic_fetch_sub_explicit(
    volatile atomic<integral-type>* p, integral-type i,
    memory_order order) noexcept;
integral-type atomic_fetch_sub_explicit(
    atomic<integral-type>* p, integral-type i, memory_order order)
    noexcept;

效果

return p->fetch_sub(i,order);

std::atomic<integral-type>::fetch_and 成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位与操作后,替换原值。

声明

integral-type fetch_and(
    integral-type i,memory_order order = memory_order_seq_cst)
    volatile noexcept;
integral-type fetch_and(
    integral-type i,memory_order order = memory_order_seq_cst) noexcept;

效果
原子的查询this中的值,将old-value&i的和存回this。

返回
返回*this之前存储的值。

抛出

NOTE:对于*this的内存地址来说,这是一个“读-改-写”操作。

std::atomic_fetch_and 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位与操作后,替换原值。

声明

integral-type atomic_fetch_and(
    volatile atomic<integral-type>* p, integral-type i) noexcept;
integral-type atomic_fetch_and(
    atomic<integral-type>* p, integral-type i) noexcept;

效果

return p->fetch_and(i);

std::atomic_fetch_and_explicit 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位与操作后,替换原值。

声明

integral-type atomic_fetch_and_explicit(
    volatile atomic<integral-type>* p, integral-type i,
    memory_order order) noexcept;
integral-type atomic_fetch_and_explicit(
    atomic<integral-type>* p, integral-type i, memory_order order)
    noexcept;

效果

return p->fetch_and(i,order);

std::atomic<integral-type>::fetch_or 成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位或操作后,替换原值。

声明

integral-type fetch_or(
    integral-type i,memory_order order = memory_order_seq_cst)
    volatile noexcept;
integral-type fetch_or(
    integral-type i,memory_order order = memory_order_seq_cst) noexcept;

效果
原子的查询this中的值,将old-value|i的和存回this。

返回
返回*this之前存储的值。

抛出

NOTE:对于*this的内存地址来说,这是一个“读-改-写”操作。

std::atomic_fetch_or 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位或操作后,替换原值。

声明

integral-type atomic_fetch_or(
    volatile atomic<integral-type>* p, integral-type i) noexcept;
integral-type atomic_fetch_or(
    atomic<integral-type>* p, integral-type i) noexcept;

效果

return p->fetch_or(i);

std::atomic_fetch_or_explicit 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位或操作后,替换原值。

声明

integral-type atomic_fetch_or_explicit(
    volatile atomic<integral-type>* p, integral-type i,
    memory_order order) noexcept;
integral-type atomic_fetch_or_explicit(
    atomic<integral-type>* p, integral-type i, memory_order order)
    noexcept;

效果

return p->fetch_or(i,order);

std::atomic<integral-type>::fetch_xor 成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位亦或操作后,替换原值。

声明

integral-type fetch_xor(
    integral-type i,memory_order order = memory_order_seq_cst)
    volatile noexcept;
integral-type fetch_xor(
    integral-type i,memory_order order = memory_order_seq_cst) noexcept;

效果
原子的查询this中的值,将old-value^i的和存回this。

返回
返回*this之前存储的值。

抛出

NOTE:对于*this的内存地址来说,这是一个“读-改-写”操作。

std::atomic_fetch_xor 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位异或操作后,替换原值。

声明

integral-type atomic_fetch_xor_explicit(
    volatile atomic<integral-type>* p, integral-type i,
    memory_order order) noexcept;
integral-type atomic_fetch_xor_explicit(
    atomic<integral-type>* p, integral-type i, memory_order order)
    noexcept;

效果

return p->fetch_xor(i,order);

std::atomic_fetch_xor_explicit 非成员函数

atomic<integral-type>实例中原子的读取一个值,并且将其与给定i值进行位异或操作后,替换原值。

声明

integral-type atomic_fetch_xor_explicit(
    volatile atomic<integral-type>* p, integral-type i,
    memory_order order) noexcept;
integral-type atomic_fetch_xor_explicit(
    atomic<integral-type>* p, integral-type i, memory_order order)
    noexcept;

效果

return p->fetch_xor(i,order);

std::atomic<integral-type>::operator++ 前置递增操作

原子的将*this中存储的值加1,并返回新值。

声明

integral-type operator++() volatile noexcept;
integral-type operator++() noexcept;

效果

return this->fetch_add(1) + 1;

std::atomic<integral-type>::operator++ 后置递增操作

原子的将*this中存储的值加1,并返回旧值。

声明

integral-type operator++() volatile noexcept;
integral-type operator++() noexcept;

效果

return this->fetch_add(1);

std::atomic<integral-type>::operator– 前置递减操作

原子的将*this中存储的值减1,并返回新值。

声明

integral-type operator--() volatile noexcept;
integral-type operator--() noexcept;

效果

return this->fetch_add(1) - 1;

std::atomic<integral-type>::operator– 后置递减操作

原子的将*this中存储的值减1,并返回旧值。

声明

integral-type operator--() volatile noexcept;
integral-type operator--() noexcept;

效果

return this->fetch_add(1);

std::atomic<integral-type>::operator+= 复合赋值操作

原子的将给定值与*this中的值相加,并返回新值。

声明

integral-type operator+=(integral-type i) volatile noexcept;
integral-type operator+=(integral-type i) noexcept;

效果

return this->fetch_add(i) + i;

std::atomic<integral-type>::operator-= 复合赋值操作

原子的将给定值与*this中的值相减,并返回新值。

声明

integral-type operator-=(integral-type i) volatile noexcept;
integral-type operator-=(integral-type i) noexcept;

效果

return this->fetch_sub(i,std::memory_order_seq_cst) – i;

std::atomic<integral-type>::operator&= 复合赋值操作

原子的将给定值与*this中的值相与,并返回新值。

声明

integral-type operator&=(integral-type i) volatile noexcept;
integral-type operator&=(integral-type i) noexcept;

效果

return this->fetch_and(i) & i;

std::atomic<integral-type>::operator|= 复合赋值操作

原子的将给定值与*this中的值相或,并返回新值。

声明

integral-type operator|=(integral-type i) volatile noexcept;
integral-type operator|=(integral-type i) noexcept;

效果

return this->fetch_or(i,std::memory_order_seq_cst) | i;

std::atomic<integral-type>::operator^= 复合赋值操作

原子的将给定值与*this中的值相亦或,并返回新值。

声明

integral-type operator^=(integral-type i) volatile noexcept;
integral-type operator^=(integral-type i) noexcept;

效果

return this->fetch_xor(i,std::memory_order_seq_cst) ^ i;

std::atomic<T*> 局部特化

std::atomic<T*>std::atomic特化了指针类型原子变量,并提供了一系列相关操作。

std::atomic<T*>是CopyConstructible(拷贝构造)和CopyAssignable(拷贝赋值)的,因为操作是原子的,在同一时间只能执行一个操作。

类型定义

template<typename T>
struct atomic<T*>
{
  atomic() noexcept = default;
  constexpr atomic(T*) noexcept;
  bool operator=(T*) volatile;
  bool operator=(T*);

  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(T*,memory_order = memory_order_seq_cst) volatile noexcept;
  void store(T*,memory_order = memory_order_seq_cst) noexcept;
  T* load(memory_order = memory_order_seq_cst) const volatile noexcept;
  T* load(memory_order = memory_order_seq_cst) const noexcept;
  T* exchange(T*,memory_order = memory_order_seq_cst) volatile noexcept;
  T* exchange(T*,memory_order = memory_order_seq_cst) noexcept;

  bool compare_exchange_strong(
      T* & old_value, T* new_value,
      memory_order order = memory_order_seq_cst) volatile noexcept;
  bool compare_exchange_strong(
      T* & old_value, T* new_value,
      memory_order order = memory_order_seq_cst) noexcept;
  bool compare_exchange_strong(
      T* & old_value, T* new_value,
      memory_order success_order,memory_order failure_order)  
      volatile noexcept;
  bool compare_exchange_strong(
      T* & old_value, T* new_value,
      memory_order success_order,memory_order failure_order) noexcept;
  bool compare_exchange_weak(
      T* & old_value, T* new_value,
      memory_order order = memory_order_seq_cst) volatile noexcept;
  bool compare_exchange_weak(
      T* & old_value, T* new_value,
      memory_order order = memory_order_seq_cst) noexcept;
  bool compare_exchange_weak(
      T* & old_value, T* new_value,
      memory_order success_order,memory_order failure_order)
      volatile noexcept;
  bool compare_exchange_weak(
      T* & old_value, T* new_value,
      memory_order success_order,memory_order failure_order) noexcept;

  operator T*() const volatile noexcept;
  operator T*() const noexcept;

  T* fetch_add(
      ptrdiff_t,memory_order = memory_order_seq_cst) volatile noexcept;
  T* fetch_add(
      ptrdiff_t,memory_order = memory_order_seq_cst) noexcept;
  T* fetch_sub(
      ptrdiff_t,memory_order = memory_order_seq_cst) volatile noexcept;
  T* fetch_sub(
      ptrdiff_t,memory_order = memory_order_seq_cst) noexcept;

  T* operator++() volatile noexcept;
  T* operator++() noexcept;
  T* operator++(int) volatile noexcept;
  T* operator++(int) noexcept;
  T* operator--() volatile noexcept;
  T* operator--() noexcept;
  T* operator--(int) volatile noexcept;
  T* operator--(int) noexcept;

  T* operator+=(ptrdiff_t) volatile noexcept;
  T* operator+=(ptrdiff_t) noexcept;
  T* operator-=(ptrdiff_t) volatile noexcept;
  T* operator-=(ptrdiff_t) noexcept;
};

bool atomic_is_lock_free(volatile const atomic<T*>*) noexcept;
bool atomic_is_lock_free(const atomic<T*>*) noexcept;
void atomic_init(volatile atomic<T*>*, T*) noexcept;
void atomic_init(atomic<T*>*, T*) noexcept;
T* atomic_exchange(volatile atomic<T*>*, T*) noexcept;
T* atomic_exchange(atomic<T*>*, T*) noexcept;
T* atomic_exchange_explicit(volatile atomic<T*>*, T*, memory_order)
  noexcept;
T* atomic_exchange_explicit(atomic<T*>*, T*, memory_order) noexcept;
void atomic_store(volatile atomic<T*>*, T*) noexcept;
void atomic_store(atomic<T*>*, T*) noexcept;
void atomic_store_explicit(volatile atomic<T*>*, T*, memory_order)
  noexcept;
void atomic_store_explicit(atomic<T*>*, T*, memory_order) noexcept;
T* atomic_load(volatile const atomic<T*>*) noexcept;
T* atomic_load(const atomic<T*>*) noexcept;
T* atomic_load_explicit(volatile const atomic<T*>*, memory_order) noexcept;
T* atomic_load_explicit(const atomic<T*>*, memory_order) noexcept;
bool atomic_compare_exchange_strong(
  volatile atomic<T*>*,T* * old_value,T* new_value) noexcept;
bool atomic_compare_exchange_strong(
  volatile atomic<T*>*,T* * old_value,T* new_value) noexcept;
bool atomic_compare_exchange_strong_explicit(
  atomic<T*>*,T* * old_value,T* new_value,
  memory_order success_order,memory_order failure_order) noexcept;
bool atomic_compare_exchange_strong_explicit(
  atomic<T*>*,T* * old_value,T* new_value,
  memory_order success_order,memory_order failure_order) noexcept;
bool atomic_compare_exchange_weak(
  volatile atomic<T*>*,T* * old_value,T* new_value) noexcept;
bool atomic_compare_exchange_weak(
  atomic<T*>*,T* * old_value,T* new_value) noexcept;
bool atomic_compare_exchange_weak_explicit(
  volatile atomic<T*>*,T* * old_value, T* new_value,
  memory_order success_order,memory_order failure_order) noexcept;
bool atomic_compare_exchange_weak_explicit(
  atomic<T*>*,T* * old_value, T* new_value,
  memory_order success_order,memory_order failure_order) noexcept;

T* atomic_fetch_add(volatile atomic<T*>*, ptrdiff_t) noexcept;
T* atomic_fetch_add(atomic<T*>*, ptrdiff_t) noexcept;
T* atomic_fetch_add_explicit(
  volatile atomic<T*>*, ptrdiff_t, memory_order) noexcept;
T* atomic_fetch_add_explicit(
  atomic<T*>*, ptrdiff_t, memory_order) noexcept;
T* atomic_fetch_sub(volatile atomic<T*>*, ptrdiff_t) noexcept;
T* atomic_fetch_sub(atomic<T*>*, ptrdiff_t) noexcept;
T* atomic_fetch_sub_explicit(
  volatile atomic<T*>*, ptrdiff_t, memory_order) noexcept;
T* atomic_fetch_sub_explicit(
  atomic<T*>*, ptrdiff_t, memory_order) noexcept;

在主模板中也提供了一些相同的操作(可见11.3.8节)。

std::atomic<T*>::fetch_add 成员函数

原子的加载一个值,然后使用与提供i相加(使用标准指针运算规则)的结果,替换掉原值。

声明

T* fetch_add(
    ptrdiff_t i,memory_order order = memory_order_seq_cst)
    volatile noexcept;
T* fetch_add(
    ptrdiff_t i,memory_order order = memory_order_seq_cst) noexcept;

效果
原子的查询this中的值,将old-value+i的和存回this。

返回
返回*this之前存储的值。

抛出

NOTE:对于*this的内存地址来说,这是一个“读-改-写”操作。

std::atomic_fetch_add 非成员函数

atomic<T*>实例中原子的读取一个值,并且将其与给定i值进行位相加操作(使用标准指针运算规则)后,替换原值。

声明

T* atomic_fetch_add(volatile atomic<T*>* p, ptrdiff_t i) noexcept;
T* atomic_fetch_add(atomic<T*>* p, ptrdiff_t i) noexcept;

效果

return p->fetch_add(i);

std::atomic_fetch_add_explicit 非成员函数

atomic<T*>实例中原子的读取一个值,并且将其与给定i值进行位相加操作(使用标准指针运算规则)后,替换原值。

声明

T* atomic_fetch_add_explicit(
     volatile atomic<T*>* p, ptrdiff_t i,memory_order order) noexcept;
T* atomic_fetch_add_explicit(
     atomic<T*>* p, ptrdiff_t i, memory_order order) noexcept;

效果

return p->fetch_add(i,order);

std::atomic<T*>::fetch_sub 成员函数

原子的加载一个值,然后使用与提供i相减(使用标准指针运算规则)的结果,替换掉原值。

声明

T* fetch_sub(
    ptrdiff_t i,memory_order order = memory_order_seq_cst)
    volatile noexcept;
T* fetch_sub(
    ptrdiff_t i,memory_order order = memory_order_seq_cst) noexcept;

效果
原子的查询this中的值,将old-value-i的和存回this。

返回
返回*this之前存储的值。

抛出

NOTE:对于*this的内存地址来说,这是一个“读-改-写”操作。

std::atomic_fetch_sub 非成员函数

atomic<T*>实例中原子的读取一个值,并且将其与给定i值进行位相减操作(使用标准指针运算规则)后,替换原值。

声明

T* atomic_fetch_sub(volatile atomic<T*>* p, ptrdiff_t i) noexcept;
T* atomic_fetch_sub(atomic<T*>* p, ptrdiff_t i) noexcept;

效果

return p->fetch_sub(i);

std::atomic_fetch_sub_explicit 非成员函数

atomic<T*>实例中原子的读取一个值,并且将其与给定i值进行位相减操作(使用标准指针运算规则)后,替换原值。

声明

T* atomic_fetch_sub_explicit(
     volatile atomic<T*>* p, ptrdiff_t i,memory_order order) noexcept;
T* atomic_fetch_sub_explicit(
     atomic<T*>* p, ptrdiff_t i, memory_order order) noexcept;

效果

return p->fetch_sub(i,order);

std::atomic<T*>::operator++ 前置递增操作

原子的将*this中存储的值加1(使用标准指针运算规则),并返回新值。

声明

T* operator++() volatile noexcept;
T* operator++() noexcept;

效果

return this->fetch_add(1) + 1;

std::atomic<T*>::operator++ 后置递增操作

原子的将*this中存储的值加1(使用标准指针运算规则),并返回旧值。

声明

T* operator++() volatile noexcept;
T* operator++() noexcept;

效果

return this->fetch_add(1);

std::atomic<T*>::operator– 前置递减操作

原子的将*this中存储的值减1(使用标准指针运算规则),并返回新值。

声明

T* operator--() volatile noexcept;
T* operator--() noexcept;

效果

return this->fetch_sub(1) - 1;

std::atomic<T*>::operator– 后置递减操作

原子的将*this中存储的值减1(使用标准指针运算规则),并返回旧值。

声明

T* operator--() volatile noexcept;
T* operator--() noexcept;

效果

return this->fetch_sub(1);

std::atomic<T*>::operator+= 复合赋值操作

原子的将*this中存储的值与给定值相加(使用标准指针运算规则),并返回新值。

声明

T* operator+=(ptrdiff_t i) volatile noexcept;
T* operator+=(ptrdiff_t i) noexcept;

效果

return this->fetch_add(i) + i;

std::atomic<T*>::operator-= 复合赋值操作

原子的将*this中存储的值与给定值相减(使用标准指针运算规则),并返回新值。

声明

T* operator+=(ptrdiff_t i) volatile noexcept;
T* operator+=(ptrdiff_t i) noexcept;

效果

return this->fetch_add(i) - i;

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!