C++11引入了原子操作,这些操作是线程安全的,并且由编译器和处理器保证在多线程环境中的原子性。原子操作通常用于实现无锁的数据结构和同步机制。以下是一些C++11中std::atomic
类型的原子操作的示例:
-
基本的原子变量定义:
#include <atomic> std::atomic<int> atomicInt(0); // 定义一个原子整数
-
原子加载(读取)操作:
int value = atomicInt.load(); // 原子地读取atomicInt的值
-
原子存储(写入)操作:
atomicInt.store(10); // 原子地将10存储到atomicInt
-
原子交换操作:
int oldValue = atomicInt.exchange(20); // 原子地将20存储到atomicInt,并返回旧值
-
原子比较并交换操作(也称为CAS操作):
int expected = 10; int desired = 20; bool success = atomicInt.compare_exchange_weak(expected, desired); // 如果atomicInt原来的值是expected,则将其设置为desired,success为true // 如果不是,expected会被更新为atomicInt的当前值,success为false
-
原子增加操作:
atomicInt.fetch_add(5, std::memory_order_relaxed); // 原子地将5加到atomicInt上
-
原子减少操作:
atomicInt.fetch_sub(3, std::memory_order_relaxed); // 原子地从atomicInt减去3
-
原子位操作:
atomicInt.fetch_or(0x01, std::memory_order_relaxed); // 原子地对atomicInt进行位或操作 atomicInt.fetch_and(~0x01, std::memory_order_relaxed); // 原子地对atomicInt进行位与操作 atomicInt.fetch_xor(0x02, std::memory_order_relaxed); // 原子地对atomicInt进行位异或操作
-
使用内存顺序:
// 使用不同的内存顺序来控制操作的可见性和顺序 atomicInt.store(100, std::memory_order_release); // 释放内存顺序,确保之前的写入对其他线程可见 int value = atomicInt.load(std::memory_order_acquire); // 获得内存顺序,确保之后的读取操作不会跳过之前的写入
-
原子变量作为锁:
std::atomic_flag spinlock = ATOMIC_FLAG_INIT; spinlock.test_and_set(); // 尝试设置锁,如果成功则继续执行,否则等待 // 临界区 spinlock.clear(); // 释放锁
原子操作是实现并发程序中同步机制的关键工具,它们提供了一种避免使用传统互斥锁(mutex)的方法,可以减少锁的开销,提高程序的性能。然而,使用原子操作时也需要谨慎,以避免造成死锁或其它同步问题。