Namespaces
Variants

std:: atomic

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
atomic
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
定义于头文件 <atomic>
template < class T >
struct atomic ;
(1) (C++11 起)
template < class U >
struct atomic < U * > ;
(2) (C++11 起)
定义于头文件 <memory>
template < class U >
struct atomic < std:: shared_ptr < U >> ;
(3) (C++20 起)
template < class U >
struct atomic < std:: weak_ptr < U >> ;
(4) (C++20 起)
定义于头文件 <stdatomic.h>
#define _Atomic(T) /* 见下文 */
(5) (C++23 起)

每个 std::atomic 模板的实例化和全特化都定义了一个原子类型。如果一个线程向原子对象执行写入操作,同时另一线程从中读取,其行为是明确定义的(关于数据竞争的详细信息请参阅 内存模型 )。

此外,对原子对象的访问可以建立线程间同步,并根据 std::memory_order 的规定对非原子内存访问进行排序。

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

在头文件 <stdatomic.h> 中提供了兼容性宏 _Atomic ,使得当两者均格式正确时, _Atomic(T) std::atomic<T> 完全相同。

未指定当包含 <stdatomic.h> 时,命名空间 std 中的任何声明是否可用。

(C++23 起)

目录

特化

主模板

主要的 std::atomic 模板可通过任何满足 TriviallyCopyable 类型 T 进行实例化,该类型需同时满足 CopyConstructible CopyAssignable 要求。若以下任一值为 false ,则程序非良构:

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

std :: atomic < bool > 使用主模板。它被保证是一个 标准布局结构体 ,并具有 平凡析构函数

部分特化

标准库为以下类型提供了 std::atomic 模板的部分特化,这些特化具有主模板所不具备的附加属性:

2) 针对所有指针类型的 std::atomic<U*> 部分特化。这些特化具有标准布局 、平凡默认构造函数 (C++20 前) 和平凡析构函数。除了为所有原子类型提供的操作外,这些特化还额外支持适用于指针类型的原子算术操作,例如 fetch_add fetch_sub
3,4) 部分特化 std :: atomic < std:: shared_ptr < U >> std :: atomic < std:: weak_ptr < U >> std::shared_ptr std::weak_ptr 提供。

详见 std::atomic <std::shared_ptr> std::atomic <std::weak_ptr>

(自 C++20 起)

整型类型的特化版本

当使用以下整数类型进行实例化时, std::atomic 会提供适用于整数类型的额外原子操作,例如 fetch_add fetch_sub fetch_and fetch_or fetch_xor

  • 字符类型 char char8_t (C++20 起) char16_t char32_t wchar_t
  • 标准有符号整数类型: signed char short int long long long
  • 标准无符号整数类型: unsigned char unsigned short unsigned int unsigned long unsigned long long
  • 头文件 <cstdint> 中 typedef 所需的任何附加整数类型。

此外,生成的 std::atomic< Integral > 特化具有标准布局 、平凡默认构造函数 (C++20 前) 和平凡析构函数。有符号整数运算定义为使用二进制补码;不存在未定义结果。

浮点类型的特化

当使用无 cv 限定的浮点类型( float double long double 及无 cv 限定的 扩展浮点类型 (C++23 起) )进行实例化时, std::atomic 会提供适用于浮点类型的额外原子操作,例如 fetch_add fetch_sub

此外,生成的 std::atomic< Floating > 特化具有标准布局和平凡析构函数。

即使结果在浮点类型中不可表示,所有操作也不会导致未定义行为。生效的 浮点环境 可能与调用线程的浮点环境不同。

(C++20 起)

成员类型

类型 定义
value_type T (无论是否特化)
difference_type [1]

value_type (仅适用于 atomic< Integral > atomic< Floating > (C++20 起) 特化版本)

std::ptrdiff_t (仅适用于 std::atomic<U*> 特化版本)

  1. difference_type 未在主模板 std::atomic 或针对 std::shared_ptr std::weak_ptr 的偏特化中定义。

成员函数

构造原子对象
(公开成员函数)
向原子对象存储值
(公开成员函数)
检查原子对象是否无锁
(公开成员函数)
以非原子参数原子性地替换原子对象的值
(公开成员函数)
原子性地获取原子对象的值
(公开成员函数)
从原子对象加载值
(公开成员函数)
原子性地替换原子对象的值并获取先前持有的值
(公开成员函数)
原子性地比较原子对象的值与非原子参数,相等时执行原子交换,不相等时执行原子加载
(公开成员函数)
(C++20)
阻塞线程直至被通知且原子值发生变化
(公开成员函数)
(C++20)
通知至少一个等待原子对象的线程
(公开成员函数)
(C++20)
通知所有阻塞等待原子对象的线程
(公开成员函数)

常量

[static] (C++17)
指示该类型始终为无锁
(公开静态成员常量)

特化成员函数

专用于整型 、浮点型 (C++20 起) 及指针类型
原子地将参数与原子对象中存储的值相加,并获取先前持有的值
(公开成员函数)
原子地从原子对象中存储的值减去参数,并获取先前持有的值
(公开成员函数)
对原子值进行加法或减法运算
(公开成员函数)
仅专用于整型及指针类型
(C++26)
原子地执行参数与原子对象值之间的 std::max 操作,并获取先前持有的值
(公开成员函数)
(C++26)
原子地执行参数与原子对象值之间的 std::min 操作,并获取先前持有的值
(公开成员函数)
将原子值递增或递减一
(公开成员函数)
仅专用于整型
原子地在参数与原子对象值之间执行按位与操作,并获取先前持有的值
(公开成员函数)
原子地在参数与原子对象值之间执行按位或操作,并获取先前持有的值
(公开成员函数)
原子地在参数与原子对象值之间执行按位异或操作,并获取先前持有的值
(公开成员函数)
对原子值执行按位与、或、异或操作
(公开成员函数)

类型别名

bool 及上述所有整型类型提供了类型别名,如下所示:

所有 std::atomic<Integral> 的别名
atomic_bool
(C++11)
std :: atomic < bool >
(类型定义)
atomic_char
(C++11)
std :: atomic < char >
(typedef)
atomic_schar
(C++11)
std :: atomic < signed char >
(类型定义)
atomic_uchar
(C++11)
std :: atomic < unsigned char >
(类型定义)
atomic_short
(C++11)
std :: atomic < short >
(类型定义)
atomic_ushort
(C++11)
std :: atomic < unsigned short >
(类型定义)
atomic_int
(C++11)
std :: atomic < int >
(类型定义)
atomic_uint
(C++11)
std :: atomic < unsigned int >
(类型定义)
atomic_long
(C++11)
std :: atomic < long >
(类型别名)
atomic_ulong
(C++11)
std :: atomic < unsigned long >
(类型别名)
atomic_llong
(C++11)
std :: atomic < long long >
(类型定义)
atomic_ullong
(C++11)
std :: atomic < unsigned long long >
(类型定义)
atomic_char8_t
(C++20)
std :: atomic < char8_t >
(类型别名)
atomic_char16_t
(C++11)
std :: atomic < char16_t >
(类型别名)
atomic_char32_t
(C++11)
std :: atomic < char32_t >
(类型别名)
atomic_wchar_t
(C++11)
std :: atomic < wchar_t >
(类型别名)
atomic_int8_t
(C++11) (可选)
std :: atomic < std:: int8_t >
(类型别名)
atomic_uint8_t
(C++11) (可选)
std :: atomic < std:: uint8_t >
(类型别名)
atomic_int16_t
(C++11) (可选)
std :: atomic < std:: int16_t >
(类型定义)
atomic_uint16_t
(C++11) (可选)
std :: atomic < std:: uint16_t >
(类型别名)
atomic_int32_t
(C++11) (可选)
std :: atomic < std:: int32_t >
(类型别名)
atomic_uint32_t
(C++11) (可选)
std :: atomic < std:: uint32_t >
(类型别名)
atomic_int64_t
(C++11) (可选)
std :: atomic < std:: int64_t >
(类型别名)
atomic_uint64_t
(C++11) (可选)
std :: atomic < std:: uint64_t >
(类型别名)
atomic_int_least8_t
(C++11)
std :: atomic < std:: int_least8_t >
(类型别名)
atomic_uint_least8_t
(C++11)
std :: atomic < std:: uint_least8_t >
(类型别名)
atomic_int_least16_t
(C++11)
std :: atomic < std:: int_least16_t >
(类型别名)
atomic_uint_least16_t
(C++11)
std :: atomic < std:: uint_least16_t >
(类型别名)
atomic_int_least32_t
(C++11)
std :: atomic < std:: int_least32_t >
(类型别名)
atomic_uint_least32_t
(C++11)
std :: atomic < std:: uint_least32_t >
(类型别名)
atomic_int_least64_t
(C++11)
std :: atomic < std:: int_least64_t >
(类型定义)
atomic_uint_least64_t
(C++11)
std :: atomic < std:: uint_least64_t >
(类型定义)
atomic_int_fast8_t
(C++11)
std :: atomic < std:: int_fast8_t >
(类型别名)
atomic_uint_fast8_t
(C++11)
std :: atomic < std:: uint_fast8_t >
(类型别名)
atomic_int_fast16_t
(C++11)
std :: atomic < std:: int_fast16_t >
(类型定义)
atomic_uint_fast16_t
(C++11)
std :: atomic < std:: uint_fast16_t >
(类型别名)
atomic_int_fast32_t
(C++11)
std :: atomic < std:: int_fast32_t >
(类型别名)
atomic_uint_fast32_t
(C++11)
std :: atomic < std:: uint_fast32_t >
(类型别名)
atomic_int_fast64_t
(C++11)
std :: atomic < std:: int_fast64_t >
(typedef)
atomic_uint_fast64_t
(C++11)
std :: atomic < std:: uint_fast64_t >
(类型别名)
atomic_intptr_t
(C++11) (可选)
std :: atomic < std:: intptr_t >
(类型别名)
atomic_uintptr_t
(C++11) (可选)
std :: atomic < std:: uintptr_t >
(类型别名)
atomic_size_t
(C++11)
std :: atomic < std:: size_t >
(类型别名)
atomic_ptrdiff_t
(C++11)
std :: atomic < std:: ptrdiff_t >
(类型定义)
atomic_intmax_t
(C++11)
std :: atomic < std:: intmax_t >
(类型别名)
atomic_uintmax_t
(C++11)
std :: atomic < std:: uintmax_t >
(类型别名)
专用类型的别名
atomic_signed_lock_free
(C++20)
一种无锁且等待/通知操作最高效的有符号整型原子类型
(类型别名)
atomic_unsigned_lock_free
(C++20)
一种无锁且等待/通知操作最高效的无符号整型原子类型
(类型别名)
Note: std::atomic_int N _t , std::atomic_uint N _t , std::atomic_intptr_t , and std::atomic_uintptr_t are defined if and only if std::int N _t , std::uint N _t , std::intptr_t , and std::uintptr_t are defined, respectively.

std::atomic_signed_lock_free std::atomic_unsigned_lock_free 在独立实现中是可选的。

(C++20 起)

注释

针对 std::atomic 的所有成员函数,均存在对应的非成员函数模板版本。这些非成员函数还可针对非 std::atomic 特化类型进行重载,前提是这些类型能确保原子性操作。标准库中唯一符合此条件的类型是 std:: shared_ptr < U >

_Atomic 是C语言中的一个 关键字 ,用于提供 原子类型

建议实现确保 C 语言中的 _Atomic(T) 与 C++ 中 std::atomic<T> 对于所有可能的类型 T 具有相同的表示形式。用于保证原子性和内存顺序的机制应当相互兼容。

在 GCC 和 Clang 上,此处描述的某些功能需要链接 -latomic 库。

特性测试 标准 特性
__cpp_lib_atomic_ref 201806L (C++20) std::atomic_ref
__cpp_lib_constexpr_atomic 202411L (C++26) constexpr std::atomic std::atomic_ref

示例

#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
std::atomic_int acnt;
int cnt;
void f()
{
    for (auto n{10000}; n; --n)
    {
        ++acnt;
        ++cnt;
        // 注意:此示例中使用宽松内存序已足够,
        // 例如 acnt.fetch_add(1, std::memory_order_relaxed);
    }
}
int main()
{
    {
        std::vector<std::jthread> pool;
        for (int n = 0; n < 10; ++n)
            pool.emplace_back(f);
    }
    std::cout << "原子计数器值为 " << acnt << '\n'
              << "非原子计数器值为 " << cnt << '\n';
}

可能的输出:

原子计数器值为 100000
非原子计数器值为 69696

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 发布行为 正确行为
LWG 2441 C++11 缺少针对 固定宽度整数类型
的原子版本 optional 的 typedef
已添加
LWG 3012 C++11 std::atomic<T> 允许用于任何可平凡复制
但不可复制的 T
禁止此类特化
LWG 3949 C++17 要求 std :: atomic < bool > 具有平凡析构函数
的措辞在 C++17 中被意外删除
已恢复
LWG 4069
( P3323R1 )
C++11 对 cv 限定 T 的支持存在疑问 禁止 T 为 cv 限定类型
P0558R1 C++11 原子类型某些函数的模板参数推导
可能意外失败;提供了无效的指针操作
规范已彻底重写:
添加了成员类型定义 value_type
difference_type

另请参阅

无锁布尔原子类型
(类)
原子共享指针
(类模板特化)
原子弱指针
(类模板特化)
C 文档 关于 原子类型