std::atomic

定义于头文件 <atomic>
template< class T >
struct atomic;
(1) (C++11 起)
template<>
struct atomic<Integral>;
(2) (C++11 起)
template<>
struct atomic<bool>;
(3) (C++11 起)
template< class T >
struct atomic<T*>;
(4) (C++11 起)
template<>
struct atomic<Floating>;
(5) (C++20 起)

每个 std::atomic 模板的实例化和完全特化定义一个原子类型。若一个线程写入原子对象,同时另一线程从它读取,则行为良好定义(数据竞争的细节见内存模型)。

而且,对原子对象的访问可以建立线程间同步,并按 std::memory_order 所对非原子内存访问定序。

std::atomic 既不可复制亦不可移动。

目录

用户定义特化

std::atomic 可对任何可平凡复制 (TriviallyCopyable) 类型 T 实例化:

struct Counters { int a; int b; }; // 用户定义可平凡复制类型
std::atomic<Counters> cnt;         // 用户定义类型的特化

标准库特化

标准库在头文件 <atomic> 中为下列类型提供 std::atomic 模板的特化:

(注意这些特化拥有用户定义特化所不拥有的额外属性)

1) 对所有指针类型的部分特化 std::atomic<T*> 。这些特化拥有标准布局、平凡默认构造函数和平凡析构函数。它们支持聚合初始化语法。在为所有原子类型提供的操作外,这些特化额外支持适合指针类型的原子算术运算,例如 fetch_addfetch_sub

2) 为类型 bool 提供一个全特化,并定义其 typedef 名,它被当做非特化的 std::atomic<T> ,除了它拥有标准布局、平凡默认构造函数和平凡析构函数,并支持聚合初始化语法:

typedef 名 全特化
std::atomic_bool std::atomic<bool>

3) 对于整数类型的全特化和 typedef ,如下:

typedef 名 全特化
std::atomic_char std::atomic<char>
std::atomic_schar std::atomic<signed char>
std::atomic_uchar std::atomic<unsigned char>
std::atomic_short std::atomic<short>
std::atomic_ushort std::atomic<unsigned short>
std::atomic_int std::atomic<int>
std::atomic_uint std::atomic<unsigned int>
std::atomic_long std::atomic<long>
std::atomic_ulong std::atomic<unsigned long>
std::atomic_llong std::atomic<long long>
std::atomic_ullong std::atomic<unsigned long long>
std::atomic_char16_t std::atomic<char16_t>
std::atomic_char32_t std::atomic<char32_t>
std::atomic_wchar_t std::atomic<wchar_t>
std::atomic_int8_t std::atomic<std::int8_t>
std::atomic_uint8_t std::atomic<std::uint8_t>
std::atomic_int16_t std::atomic<std::int16_t>
std::atomic_uint16_t std::atomic<std::uint16_t>
std::atomic_int32_t std::atomic<std::int32_t>
std::atomic_uint32_t std::atomic<std::uint32_t>
std::atomic_int64_t std::atomic<std::int64_t>
std::atomic_uint64_t std::atomic<std::uint64_t>
std::atomic_int_least8_t std::atomic<std::int_least8_t>
std::atomic_uint_least8_t std::atomic<std::uint_least8_t>
std::atomic_int_least16_t std::atomic<std::int_least16_t>
std::atomic_uint_least16_t std::atomic<std::uint_least16_t>
std::atomic_int_least32_t std::atomic<std::int_least32_t>
std::atomic_uint_least32_t std::atomic<std::uint_least32_t>
std::atomic_int_least64_t std::atomic<std::int_least64_t>
std::atomic_uint_least64_t std::atomic<std::uint_least64_t>
std::atomic_int_fast8_t std::atomic<std::int_fast8_t>
std::atomic_uint_fast8_t std::atomic<std::uint_fast8_t>
std::atomic_int_fast16_t std::atomic<std::int_fast16_t>
std::atomic_uint_fast16_t std::atomic<std::uint_fast16_t>
std::atomic_int_fast32_t std::atomic<std::int_fast32_t>
std::atomic_uint_fast32_t std::atomic<std::uint_fast32_t>
std::atomic_int_fast64_t std::atomic<std::int_fast64_t>
std::atomic_uint_fast64_t std::atomic<std::uint_fast64_t>
std::atomic_intptr_t std::atomic<std::intptr_t>
std::atomic_uintptr_t std::atomic<std::uintptr_t>
std::atomic_size_t std::atomic<std::size_t>
std::atomic_ptrdiff_t std::atomic<std::ptrdiff_t>
std::atomic_intmax_t std::atomic<std::intmax_t>
std::atomic_uintmax_t std::atomic<std::uintmax_t>

注意: std::atomic_intN_tstd::atomic_uintN_tstd::atomic_intptr_tatomic_uintptr_t 分别若且唯若定义了 std::intN_tstd::uintN_tstd::intptr_tstd::uintptr_t 才有定义。

这些特化拥有标准布局,平凡默认构造函数,以及平凡析构函数。它们支持聚合体初始化语法。在为所有原子类型提供的操作外,这些特化拥有额外的对整数类型的原子操作,例如 fetch_addfetch_subfetch_andfetch_orfetch_xor

4) 为浮点类型提供全特化(但不提供任何 typedef ):

template<> struct std::atomic<float>
template<> struct std::atomic<double>
template<> struct std::atomic<long double>

这些特化拥有标准布局、平凡构造函数和平凡析构函数。除了对所有原子类型提供的操作,这些特化拥有适合浮点类型的额外运算,如 fetch_addfetch_sub ,但非 fetch_andfetch_or 。没有操作导致未定义行为,即使结果不能以该浮点类型表示。有影响的浮点环境可能异于调用方线程的浮点环境。

(C++20 起)

成员函数

构造原子对象
(公开成员函数)
存储值于原子对象
(公开成员函数)
检查原子对象是否免锁
(公开成员函数)
原子地以非原子对象替换原子对象的值
(公开成员函数)
原子地获得原子对象的值
(公开成员函数)
从原子对象加载值
(公开成员函数)
原子地替换原子对象的值并获得它先前持有的值
(公开成员函数)
原子地比较原子对象与非原子参数的值,若相等则进行交换,若不相等则进行加载
(公开成员函数)

常量

[静态] (C++17)
指示该类型是否始终免锁
(公开静态成员常量)

特化成员函数

原子地将参数加到存储于原子对象的值,并返回先前保有的值
(公开成员函数)
原子地从存储于原子对象的值减去参数,并获得先前保有的值
(公开成员函数)
原子地进行参数和原子对象的值的逐位与,并获得先前保有的值
(公开成员函数)
原子地进行参数和原子对象的值的逐位或,并获得先前保有的值
(公开成员函数)
原子地进行参数和原子对象的值的逐位异或,并获得先前保有的值
(公开成员函数)
令原子值增加或减少一
(公开成员函数)
加、减,或与原子值进行逐位与、或、异或
(公开成员函数)

注意

存在等价于 std::atomic 所有成员函数的非成员函数模板。这些非成员函数可以额外对非 std::atomic 特化的类型重载,但不能保证原子性。标准库中仅有的这种类型是 std::shared_ptr<T>

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR 应用于 出版时的行为 正确行为
LWG 2441 C++11 添加了(可选)定宽整数类型的特化

参阅

(C++11)
免锁的布尔原子类型
(类)

引用

  • 29.5 Atomic types [atomics.types.generic]

版本历史

  • (当前 | 先前 2017年12月8日 (五) 18:18Fruderica讨论 | 贡献. . (8,645字节) (+800). . (p0020r6) (撤销)
  • 当前 | 先前 2017年10月8日 (日) 09:06Fruderica讨论 | 贡献 . . (7,845字节) (-46). . (correct) (撤销)
  • 当前 | 先前 2017年9月13日 (三) 03:48Fruderica讨论 | 贡献 . . (7,891字节) (+305). . (撤销)
  • 当前 | 先前 2017年2月3日 (五) 09:11Fruderica讨论 | 贡献. . (7,586字节) (+754). . (撤销)
  • 当前 | 先前 2015年11月30日 (一) 04:48P12讨论 | 贡献. . (6,832字节) (-456). . (Remove orig text) (撤销)
  • 当前 | 先前 2015年10月28日 (三) 07:25Liandaoacc讨论 | 贡献. . (7,288字节) (+7). . (撤销)
  • 当前 | 先前 2013年7月9日 (二) 02:05P12bot讨论 | 贡献 . . (7,281字节) (+6). . (Allow search engines to index popular pages.) (撤销)
  • 当前 | 先前 2013年7月2日 (二) 07:15P12bot讨论 | 贡献 . . (7,275字节) (-762). . (Use {{lc}}. Update links. Various fixes.) (撤销)
  • 当前 | 先前 2012年11月2日 (五) 17:05P12bot讨论 | 贡献 . . (8,037字节) (+201). . (r2.7.3) (机器人添加:de, en, es, fr, it, ja, pt, ru) (撤销)
  • 当前 | 先前 2012年10月26日 (五) 09:21P12讨论 | 贡献 . . (7,836字节) (0). . (1个修订: Translate from the English version) (撤销)
  • 当前 | 先前 2012年10月26日 (五) 06:00TranslationBot讨论 | 贡献. . (7,836字节) (-77). . (Translated from the English version using Google Translate) (撤销)
  • 当前 | 先前 2012年10月25日 (四) 13:13P12讨论 | 贡献 . . (7,913字节) (0). . (1个修订: Translate from the English version) (撤销)
  • 当前 | 先前) 2012年10月25日 (四) 12:00TranslationBot讨论 | 贡献. . (7,913字节) (+7,913). . (Translated from the English version using Google Translate)