[modern c++] compare_exchange_weak 与 CAS

参考:

https://blog.csdn.net/yand789/article/details/27324295

汇编实现:https://www.jianshu.com/p/fa6d9d9c63b4

 

compare_exchange_weak 的伪码逻辑:

if *(目标内存地址) == expected:

    *(目标内存地址) = desired;
    return true;

else:

    expected = *(目标内存地址);
    return false;

这里涉及到 三个值:

1)要检查的内存 中的值 ;

2)希望 需要检查的内存中 内应当是什么值  expected ;          (对应compare)

3)如果 需要检查的内存 中的存放的值 和 expected 一致,那么使用新值重新填充 需要检查的内存,否则使用需要检查的内存的当前值填充expected。   (对应exchange)

 

If current value of the memory location is equal to the old value, then the new value is written to the memory. In other word, we can write value into target memory only if we know the old value in the memory.

对于 指定内存位置,我们认为它应该是什么值 和 它此时此刻是什么值 如果相等,CAS或者CSW才会成功。

 

函数原型:

bool compare_exchange_weak( T& expected, T desired,
                            std::memory_order success,
                            std::memory_order failure );

用法:

std::atomic b;
bool expected;
//如果b == expected,则b = true,如果 b!=expected,则expected = b
b.compare_exchange_weak(expected,true,memory_order_acq_rel,memory_order_acquire);

通常在进行 compare_exchange_weak 后会检查 expected的值来判断本次交换是否成功。

有些平台上compare_exchange_weak可能会错误返回,所以万无一失的方法是进行loop判断:

bool expected=false;
extern atomic b; // set somewhere else
while(!b.compare_exchange_weak(expected,true) && !expected);

循环检查的语义:

检查指定内存中的值和期望的是不是一样,如果是则把希望赋予的新值写入指定内存,如果不是则读出内存中的值写入expected中(函数原型中要求expected必须是一个引用这样才能写入,所以必须是左值,右值不能作为expected),然后进入下一次循环,新的循环中expected中存的是内存地址中最新的值,因为上一次读的时候发现值不匹配(这里的不匹配是指我希望的和内存中的不匹配,如果我希望的本身就是风马牛不相及的值,第二次便会被自动设置成内存中的值,这样第二次比较才会有意义),所以再读一次。

 

你可能感兴趣的:(#,Modern,C/C++)