元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
C++基础
▶
类型系统
基本数据类型
类型推导
类型转换
▶
编译模型
翻译单元
ODR规则
头文件与实现分离
▶
作用域与生命周期
存储期类型
RAII机制
对象构造与析构
▶
面向对象编程
▶
类设计
成员访问控制
特殊成员函数
友元机制
▶
继承体系
虚函数表
多重继承
虚继承
▶
多态实现
动态绑定
RTTI机制
类型擦除
▶
模板与泛型编程
▶
模板基础
函数模板
类模板
可变参数模板
▶
模板元编程
SFINAE
类型萃取
编译期计算
▶
概念与约束
requires表达式
概念定义
约束模板
▶
内存模型
▶
内存管理
堆与栈
智能指针
移动语义
▶
对象模型
成员布局
虚函数实现
空基类优化
▶
并发内存
内存顺序
原子操作
内存屏障
▶
标准库核心
▶
容器
序列容器
关联容器
无序容器
▶
迭代器
迭代器类别
迭代器适配器
范围迭代
▶
函数对象
函数包装器
绑定表达式
lambda实现
发布时间:
2025-03-23 10:13
↑
☰
# C++原子操作详解 ## 概述 C++11引入了原子类型和原子操作,用于在多线程环境下实现无锁编程。原子操作保证了对共享数据的访问是原子的,不会被其他线程中断。本文将详细介绍C++中的原子类型、原子操作及其应用。 ## 原子类型 ### 基本原子类型 ```cpp #include <atomic> void atomicTypesExample() { std::atomic<bool> ready{false}; std::atomic<int> counter{0}; std::atomic<void*> ptr{nullptr}; // 原子操作 ready.store(true); counter.fetch_add(1); ptr.store(nullptr); } ``` ### 特化的原子类型 ```cpp // 常用特化类型 std::atomic_bool flag; std::atomic_int counter; std::atomic_size_t index; // 指针的原子类型 int value = 42; std::atomic<int*> ptr(&value); ``` ## 原子操作 ### 1. 存储和加载 ```cpp std::atomic<int> value{0}; void storeLoadExample() { // 存储操作 value.store(42); // 加载操作 int current = value.load(); // 存储-加载的组合操作 int old_value = value.exchange(100); } ``` ### 2. 算术操作 ```cpp std::atomic<int> counter{0}; void arithmeticExample() { // 自增/自减 counter++; ++counter; counter--; --counter; // 加法/减法 counter.fetch_add(5); counter.fetch_sub(3); // 返回旧值的操作 int old_value = counter.fetch_add(1); } ``` ### 3. 比较和交换 ```cpp std::atomic<int> value{0}; void compareExchangeExample() { int expected = 0; // 强CAS bool success = value.compare_exchange_strong( expected, 42 ); // 弱CAS(可能虚假失败) success = value.compare_exchange_weak( expected, 42 ); // CAS循环 while (!value.compare_exchange_weak(expected, 42)) { // 重试 } } ``` ## 内存序和同步 ### 1. 默认内存序 ```cpp std::atomic<bool> ready{false}; void defaultOrderingExample() { // 默认使用顺序一致性 ready.store(true); // memory_order_seq_cst bool status = ready.load(); // memory_order_seq_cst } ``` ### 2. 指定内存序 ```cpp std::atomic<int> data{0}; void explicitOrderingExample() { // 使用Relaxed序 data.store(42, std::memory_order_relaxed); // 使用Release-Acquire序 data.store(42, std::memory_order_release); int value = data.load(std::memory_order_acquire); } ``` ## 实际应用 ### 1. 自旋锁实现 ```cpp class SpinLock { std::atomic_flag flag = ATOMIC_FLAG_INIT; public: void lock() { while (flag.test_and_set(std::memory_order_acquire)) { // 自旋等待 } } void unlock() { flag.clear(std::memory_order_release); } }; void spinLockExample() { SpinLock lock; // 使用RAII管理锁 { std::lock_guard<SpinLock> guard(lock); // 临界区 } } ``` ### 2. 无锁计数器 ```cpp class LockFreeCounter { std::atomic<unsigned> counter{0}; public: void increment() { counter.fetch_add(1, std::memory_order_relaxed); } void decrement() { counter.fetch_sub(1, std::memory_order_relaxed); } unsigned get() const { return counter.load(std::memory_order_relaxed); } }; ``` ### 3. 无锁队列 ```cpp template<typename T> class LockFreeQueue { struct Node { T data; std::atomic<Node*> next{nullptr}; }; std::atomic<Node*> head; std::atomic<Node*> tail; public: void push(T value) { Node* new_node = new Node{value}; while (true) { Node* old_tail = tail.load(); Node* next = old_tail->next.load(); if (next == nullptr) { if (old_tail->next.compare_exchange_weak( next, new_node )) { tail.compare_exchange_strong( old_tail, new_node ); return; } } else { tail.compare_exchange_strong( old_tail, next ); } } } }; ``` ## 性能考虑 ### 1. 原子操作开销 ```cpp void performanceExample() { // 非原子操作 - 最快 int normal = 0; normal++; // 原子操作 - 有开销 std::atomic<int> atomic{0}; atomic.fetch_add(1); // 锁操作 - 最慢 std::mutex mtx; int locked = 0; { std::lock_guard<std::mutex> lock(mtx); locked++; } } ``` ### 2. 伪共享问题 ```cpp struct alignas(64) AlignedAtomic { std::atomic<int> value{0}; // 填充到缓存行大小 char padding[60]; // 64 - sizeof(atomic<int>) }; class Counter { AlignedAtomic counters[4]; // 每个计数器独占缓存行 public: void increment(int index) { counters[index].value.fetch_add(1, std::memory_order_relaxed ); } }; ``` ## 最佳实践 ### 1. 选择合适的内存序 ```cpp class OptimizedCounter { std::atomic<int> value{0}; public: // 计数器操作使用Relaxed序 void increment() { value.fetch_add(1, std::memory_order_relaxed); } // 同步点使用Acquire-Release序 void reset() { value.store(0, std::memory_order_release); } int get() const { return value.load(std::memory_order_acquire); } }; ``` ### 2. 避免ABA问题 ```cpp template<typename T> class ABA_Safe { struct Node { T data; std::atomic<uint64_t> version_ptr; }; std::atomic<uint64_t> head; public: void push(T value) { Node* new_node = new Node{value}; uint64_t old_head = head.load(); do { // 使用版本号避免ABA问题 new_node->version_ptr = old_head; } while (!head.compare_exchange_weak( old_head, reinterpret_cast<uint64_t>(new_node) )); } }; ``` ### 3. 正确使用memory_order ```cpp class SafePublisher { std::atomic<int> data{0}; std::atomic<bool> ready{false}; public: void publish(int value) { data.store(value, std::memory_order_relaxed); ready.store(true, std::memory_order_release); } bool try_consume(int& result) { if (ready.load(std::memory_order_acquire)) { result = data.load(std::memory_order_relaxed); return true; } return false; } }; ``` ## 总结 1. 原子类型的特点: - 保证操作的原子性 - 提供内存序选项 - 支持无锁编程 2. 常用操作: - 加载和存储 - 算术运算 - 比较和交换 3. 使用建议: - 选择合适的内存序 - 注意性能开销 - 避免ABA问题 - 考虑缓存影响