但是,如果您需要一次读取或更改几个变量-std :: atomic a,b,c,-并且不想实现无锁算法并解决ABA问题,那么您需要使用锁。CPU原子CAS功能(在大多数CPU中)可以检查是否仅更改了一个最大宽度为64位的变量,但是那时可以更改另一个变量。解决方案:std :: atomic 允许对T型使用任何大小的结构。
在C ++标准中,如果std :: atomic 是“普通可复制类型”,即满足条件std :: is_trivially_copyable :: value ==,则可以对T使用任何类型的T。真正
C ++标准说明了什么:http : //www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
§29.5/ 1
引用:
有一个通用的类模板atomic 。模板参数T的类型应是可复制的(3.9)。[注意:不能静态初始化的类型参数可能很难使用-尾注]
§3.9/ 9
引用:
标量类型,普通可复制类类型(第9章),此类类型的数组以及这些类型的cv限定版本(3.9.3)统称为普通可复制类型
但是,如果CPU原子CAS函数可以检查是否仅更改了一个最大宽度为64位的变量,并且我们具有三个32位变量,那么CAS函数将如何在std :: atomic 中工作?CAS函数和所减肥食谱:www.sheonline.cn 有其他函数将自动使用锁(std :: mutex或其他某个锁),该锁包含在std :: atomic 的标准实现中,用于T-普通可复制类型。
要原子地更改几个变量,我们可以使用变量结构struct T {int price,count,total; }; 作为std :: atomic 模板的类型。
示例:[5] http://coliru.stacked-crooked.com/a/bdfb3dc440eb6e51
输出示例:10、7、70
在此示例中,在任何时候,最后的值70将等于前两个值p-10 * 7的乘积-即整个结构仅发生原子变化。
用于x86的gcc和clang中的代码将使用-latomic标志进行编译。
在这种情况下,每次调用std :: atomic shared_val; 将在其中导致锁定,如功能shared_val.is_lock_free()== false的值所示。
也就是说,在全局范围内,当处理原子变量时,我们使用了乐观锁(周期),并在本地使用了2个悲观锁:获取旧值并调用CAS函数。
来源:CSDN
作者:asade12345
链接:https://blog.csdn.net/asade12345/article/details/103473650