C++ 参考手册
- C++11
- C++14
- C++17
- C++20
- C++ 编译器支持情况表
- 独立与宿主实现
- C++ 语言
- C++ 关键词
- 预处理器
- C++ 标准库头文件
- 具名要求
- 功能特性测试 (C++20)
- 工具库
- 类型支持(基本类型、RTTI、类型特性)
- 概念库 (C++20)
- 错误处理
- 动态内存管理
- 日期和时间工具
- 字符串库
- 容器库
- 迭代器库
- 范围库 (C++20)
- 算法库
- 数值库
- 输入/输出库
- 文件系统库
- 本地化库
- 正则表达式库
- 原子操作库
- std::atomic_store, std::atomic_store_explicit
- std::atomic_load, std::atomic_load_explicit
- std::atomic_exchange, std::atomic_exchange_explicit
- std::atomic
- std::atomic_flag
- std::atomic_ref
- std::atomic_compare_exchange_weak, std::atomic_compare_exchange_strong, std::atomic_compare_exchange_weak_explicit, std::atomic_compare_exchange_strong_explicit
- std::atomic_fetch_add, std::atomic_fetch_add_explicit
- std::atomic_fetch_sub, std::atomic_fetch_sub_explicit
- std::atomic_fetch_and, std::atomic_fetch_and_explicit
- std::atomic_fetch_or, std::atomic_fetch_or_explicit
- std::atomic_fetch_xor, std::atomic_fetch_xor_explicit
- std::atomic_is_lock_free, ATOMIC_xxx_LOCK_FREE
- std::atomic_wait, std::atomic_wait_explicit
- std::atomic_notify_one
- std::atomic_notify_all
- std::atomic_flag_test_and_set, std::atomic_flag_test_and_set_explicit
- std::atomic_flag_clear, std::atomic_flag_clear_explicit
- std::atomic_flag_test, std::atomic_flag_test_explicit
- std::atomic_flag_wait, std::atomic_flag_wait_explicit
- std::atomic_flag_notify_one
- std::atomic_flag_notify_all
- std::atomic_init
- ATOMIC_VAR_INIT
- ATOMIC_FLAG_INIT
- std::memory_order
- std::kill_dependency
- std::atomic_thread_fence
- std::atomic_signal_fence
- 注释
- 线程支持库
- 实验性 C++ 特性
- 有用的资源
- 索引
- std 符号索引
- 协程支持 (C++20)
- C++ 关键词
std::atomic_thread_fence
定义于头文件 <atomic>
|
||
extern "C" void atomic_thread_fence( std::memory_order order ) noexcept; |
(C++11 起) | |
建立非原子和宽松原子访问的以 order
指示的内存同步顺序,而无关联的原子操作。
栅栏原子同步
线程 A 中的释放栅栏 F 同步于线程 B 中的原子获得操作 Y ,若
- 存在原子存储 X (带任何内存顺序)
- Y 读取 X 所写入的值(或会为 X 所引领的释放序列所写入的值,若 X 是释放操作)
- F 在线程 A 中先序于 X
此情况下,所有线程 A 中先序于 F 的非原子和宽松原子存储将先发生于线程 B 中所有 Y 后的,来自同一位置的非原子和宽松原子加载。
原子栅栏同步
线程 A 中的原子释放操作 X 同步于线程 B 中的获得栅栏 F ,若
- 存在原子读取 Y (带任何内存顺序)
- Y 读取 X (或 X 所引领的释放序列)所写入的值
- Y 在线程 B 中先序于 F
此情况下,线程 A 中所有先序于 X 的非原子和宽松原子存储,将先发生于线程 B 中所有 F 后的,来自同一位置的非原子和宽松原子加载。
栅栏栅栏同步
线程 A 中的释放栅栏 FA 同步于线程 B 中的获得栅栏 FB ,若
- 存在原子对象 M ,
- 线程 A 中存在修改 M 的原子写入 X (带任何内存顺序)
- 线程 A 中 FA 先序于 X
- 线程 B 中存在原子读取 Y (带任何内存顺序)
- Y 读取 X 所写入的值(或会为 X 所引领的释放序列所写入的值,若 X 是释放操作)
- 线程 B 中 Y 先序于 FB
此情况下,线程 A 中所有先序于 FA 的非原子和宽松原子存储,将先发生于线程 B 中所有 FB 后的,来自同一位置的非原子和宽松原子加载。
参数
order | - | 此栅栏所执行的内存顺序 |
返回值
(无)
注意
atomic_thread_fence
强加的同步制约强于带同一 std::memory_order 的原子存储操作。在原子存储释放操作阻止所有前驱写入被移动到存储释放之后的同时,带 memory_order_release
顺序的 atomic_thread_fence
还阻止所有前驱写入被移动到后继存储之后。
栅栏栅栏同步能用于添加同步到数个宽松原子操作的序列,例如
// 全局 std::string computation(int); void print( std::string ); std::atomic<int> arr[3] = { -1, -1, -1 }; std::string data[1000] // 非原子数据 // 线程 A ,计算 3 个值 void ThreadA( int v0, int v1, int v2 ) { //assert( 0 <= v0, v1, v2 < 1000 ); data[v0] = computation(v0); data[v1] = computation(v1); data[v2] = computation(v2); std::atomic_thread_fence(std::memory_order_release); std::atomic_store_explicit(&arr[0], v0, std::memory_order_relaxed); std::atomic_store_explicit(&arr[1], v1, std::memory_order_relaxed); std::atomic_store_explicit(&arr[2], v2, std::memory_order_relaxed); } // 线程 B ,打印已经计算的 0 与 3 之间的值。 void ThreadB() { int v0 = std::atomic_load_explicit(&arr[0], std::memory_order_relaxed); int v1 = std::atomic_load_explicit(&arr[1], std::memory_order_relaxed); int v2 = std::atomic_load_explicit(&arr[2], std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_acquire); // v0 、 v1 、 v2 可能全部或部分结果为 -1 。 // 其他情况下读取非原子数据是安全的,因为栅栏: if( v0 != -1 ) { print( data[v0] ); } if( v1 != -1 ) { print( data[v1] ); } if( v2 != -1 ) { print( data[v2] ); } }
示例
扫描邮箱数组,并只处理我们打算处理的一个,而无不必要的同步。 此示例使用原子栅栏同步。
运行此代码
const int num_mailboxes = 32; std::atomic<int> mailbox_receiver[num_mailboxes]; std::string mailbox_data[num_mailboxes]; // 写者线程更新非原子共享数据 // 然后更新 mailbox_receiver[i] 如下 mailbox_data[i] = ...; std::atomic_store_explicit(&mailbox_receiver[i], receiver_id, std::memory_order_release); // 读者线程需要检查所有 mailbox[i] ,但只需与一个同步 for (int i = 0; i < num_mailboxes; ++i) { if (std::atomic_load_explicit(&mailbox_receiver[i], std::memory_order_relaxed) == my_id) { std::atomic_thread_fence(std::memory_order_acquire); // 恰与一个写者同步 do_work( mailbox_data[i] ); // 保证观测到 atomic_store_explicit() // 之前写者线程所做的任何事 } }
参阅
(C++11) |
为给定的原子操作定义内存顺序制约 (枚举) |
(C++11) |
线程与执行于同一线程的信号处理函数间的栅栏 (函数) |