0%

CPP原子变量

概述

原子变量是一类能保证其各个操作均为线程安全的特殊变量,是无锁编程的基础,在高性能场景中应用十分广泛。

对于普通变量而言,因为对变量的修改需要经历读取-修改-写回等步骤,因此对其的修改不是线程安全的。原子变量使用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