概述
原子变量是一类能保证其各个操作均为线程安全的特殊变量,是无锁编程的基础,在高性能场景中应用十分广泛。
对于普通变量而言,因为对变量的修改需要经历读取-修改-写回等步骤,因此对其的修改不是线程安全的。原子变量使用CAS、总线锁等机制,保证上述各个步骤不会被打断,从而保证操作的线程安全。
CPP提供了std::atomic作为原子变量,它能够接受一个可平凡复制且可移动、拷贝的类型作为模板参数。CPP中,原子变量是不可拷贝和移动的。
通用方法
对于所有合法参数类型,其提供了以下方法:
| 接口 | 含义 |
|---|---|
| bool is_lock_free() const noexcept; | 检查对该对象的全部操作是否无锁 除了std::atomic_flag外,CPP允许原子变量通过锁定操作来实现,而不是使用无锁原子CPU指令 |
| void store(T desired, std::memory_order order = std::memory_order_seq_cst) noexcept; | 使用desired对原子变量赋值 |
| T load(std::memory_order order = std::memory_order_seq_cst) const noexcept; | 取出原子变量中的值 |
| operator T() const noexcept; | 默认类型转换函数,相当于load() |
| T exchange(T desired, std::memory_order order = std::memory_order_seq_cst) noexcept; | 使用desired对原子变量赋值,并返回原子变量原值 |
| bool compare_exchange_weak(T& expected, T desired, std::memory_order order = std::memory_order_seq_cst) noexcept; bool compare_exchange_strong(T& expected, T desired, std::memory_order order = std::memory_order_seq_cst) noexcept; |
相当于原子性的执行下述操作if(*this == expected) { auto ret = *this; *this = desired; return true; } else { return false; }*this和expected间的比较为按位比较,不调用 operator==函数compare_exchange_weak和compare_exchange_strong的区别主要在,为了在某些架构处理器上获得性能优势,compare_exchange_weak被允许产生允许虚假的失败 |
只适用于整形和指针的方法
| 接口 | 含义 |
|---|---|
| T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept; T* fetch_add(std::ptrdiff_t arg, std::memory_order order = std::memory_order_seq_cst) noexcept; |
原子性的加上参数值,返回原值 |
| T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept; T* fetch_sub(std::ptrdiff_t arg, std::memory_order order = std::memory_order_seq_cst) noexcept; |
原子性的减去参数值,返回原值 |
| T operator+=(T arg) noexcept; T* operator+=(std::ptrdiff_t arg) noexcept; |
原子性的加上参数值,返回计算后的值 |
| T operator-=(T arg) noexcept; T* operator-=(std::ptrdiff_t arg) noexcept; |
原子性的减去参数值,返回计算后的值 |
| T fetch_max(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept; T* fetch_max(T* arg, std::memory_order order = std::memory_order_seq_cst) noexcept; |
原子性的将值设为当前值和传入参数间的较大值,并返回原值 |
| T fetch_min(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept; T* fetch_min(T* arg, std::memory_order order = std::memory_order_seq_cst) noexcept; |
原子性的将值设为当前值和传入参数间的较大值,并返回原值 |
| T operator++() noexcept; T* operator++(int) T* operator++() noexcept; T* operator++(int) |
原子性的加1,返回计算后的值 |
| T operator–() noexcept; T* operator–(int) T* operator–() noexcept; T* operator–(int) |
原子性的减1,返回计算后的值 |
只适用于整形的方法
| 接口 | 含义 |
|---|---|
| T fetch_and(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept; T* fetch_and(std::ptrdiff_t arg, std::memory_order order = std::memory_order_seq_cst) noexcept; |
原子性的与参数值按位与,返回原值 |
| T fetch_or(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept; T* fetch_or(std::ptrdiff_t arg, std::memory_order order = std::memory_order_seq_cst) noexcept; |
原子性的与参数值按位或,返回原值 |
| T fetch_xor(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept; T* fetch_xor(std::ptrdiff_t arg, std::memory_order order = std::memory_order_seq_cst) noexcept; |
原子性的与参数值按位异或,返回原值 |
| T operator&=(T arg) noexcept; T* operator&=(std::ptrdiff_t arg) noexcept; |
原子性的与参数值按位与,返回计算后的值 |
| T operator | =(T arg) noexcept; T* operator |
| T operator^=(T arg) noexcept; T* operator^=(std::ptrdiff_t arg) noexcept; |
原子性的与参数值按位异或,返回计算后的值 |
atomic_flag
std::atomic_flag是原子布尔类型,其总是无锁的。
其提供如下方法:
| 接口 | 含义 |
|---|---|
| bool test_and_set(std::memory_order order = std::memory_order_seq_cst) noexcept; | 设置flag为true并返回原值 |
| void clear(std::memory_order order = std::memory_order_seq_cst) noexcept; | 设置flag为false |