c++怎么使用C++20的std::atomic_ref_C++20原子引用atomic_ref用法解析

std::atomic_ref可将普通对象转为原子操作引用,适用于无法修改原类型的场景。它不拥有内存,仅提供原子视图,要求被引用对象类型可平凡复制、正确对齐且生命周期覆盖atomic_ref使用期。示例中两个线程通过atomic_ref对int进行原子递增,最终结果为2000。支持load、store、fetch_add等操作,整型指针还支持位运算,浮点型c++20起支持算术操作。可通过is_always_lock_free判断是否无锁,运行时也可调用is_lock_free查询。为确保对齐,可使用alignas指定。该工具强大但限制多,需谨慎使用以保证安全。

c++怎么使用C++20的std::atomic_ref_C++20原子引用atomic_ref用法解析

在C++20中,std::atomic_ref 提供了一种将已有普通对象包装成原子操作引用的方式,允许对非原子变量进行原子访问,而无需将其声明为 atomic 类型。这个特性特别适用于需要对已有数据结构添加原子操作能力,但又不能修改其定义的场景。

基本用法与要求

std::atomic_ref 不持有对象内存,它只是一个对已有对象的“原子视图”。创建 atomic_ref 时需传入一个对象的引用。

使用限制较多,必须满足以下条件:

  • 被引用的对象类型必须是可平凡复制(trivially copyable)
  • 对象的地址必须正确对齐(alignment)以支持原子操作
  • 对象在整个 atomic_ref 生命周期内不能被销毁
  • atomic_ref 实例本身不能被拷贝或移动(不可复制)

注意:如果对象未满足对齐或生命周期要求,行为未定义。

简单示例

下面是一个使用 std::atomic_ref 对 int 变量进行原子加的操作:

立即学习C++免费学习笔记(深入)”;

#include <iostream> #include <atomic> #include <thread>  int main() {     int value = 0;     std::atomic_ref atomic_value{value}; // 绑定到 value      auto worker = [&]() {         for (int i = 0; i < 1000; ++i) {             atomic_value.fetch_add(1, std::memory_order_relaxed);         }     };      std::thread t1(worker);     std::thread t2(worker);      t1.join();     t2.join();      std::cout << "Final value: " << value << "n"; // 应输出 2000 } 

这里,尽管 value 是普通 int,通过 atomic_ref 可以安全地在多线程中进行原子递增。

支持的操作

atomic_ref 支持大多数原子操作,具体取决于所引用类型的性质:

c++怎么使用C++20的std::atomic_ref_C++20原子引用atomic_ref用法解析

AppMall应用商店

AI应用商店,提供即时交付、按需付费的人工智能应用服务

c++怎么使用C++20的std::atomic_ref_C++20原子引用atomic_ref用法解析56

查看详情 c++怎么使用C++20的std::atomic_ref_C++20原子引用atomic_ref用法解析

  • load() / store()
  • fetch_add() / fetch_sub()
  • exchange() / compare_exchange_weak() / compare_exchange_strong()
  • fetch_and() / fetch_or() / fetch_xor() (仅整数和指针类型

浮点类型还支持 fetch_add 和 fetch_sub(C++20起)。

对齐与兼容性检查

可通过 is_always_lock_free 静态成员判断该类型是否在当前平台支持无锁原子操作:

if (std::atomic_ref<int>::is_always_lock_free) {     std::cout << "int atomic_ref is lock-freen"; } 

也可在运行时使用 .is_lock_free() 查询。

若不确定对象是否对齐,可使用 alignas 确保:

alignas(std::atomic_ref<int>) int aligned_value = 0; 

基本上就这些。std::atomic_ref 是个强大但需谨慎使用的工具,适合底层并发编程封装遗留代码的原子访问,只要注意对齐、生命周期和类型限制,就能安全发挥其作用。

上一篇
下一篇
text=ZqhQzanResources