《CAS原子操作》

1、什么是CAS原子操作
在研究无锁之前。我们须要首先了解一下CAS原子操作——Compare & Set,或是 Compare & Swap,如今差点儿所有的CPU指令都支持CAS的原子操作,X86下相应的是 CMPXCHG 汇编指令。

2、操作系统里面关于“原子操作”的概念,一个操作是原子的(atomic),假设这个操作所处的层(layer)的更高层不能发现其内部实现与结构。原子操作能够是一个步骤,也能够是多个操作步骤。可是其顺序是不能够被打乱,或者分割掉仅仅运行部分。有了这个原子操作这个保证我们就能够实现无锁了。

3、CAS原子操作在维基百科中的代码描写叙述例如以下:

    int compare_and_swap(int* reg, int oldval, int newval)
    {
        ATOMIC();
        int old_reg_val = *reg;
        if (old_reg_val == oldval)
            *reg = newval;
        END_ATOMIC();
        return old_reg_val;
    }
也就是检查内存*reg里的值是不是oldval,假设是的话。则对其赋值newval。上面的代码总是返回old_reg_value,调用者假设须要知道是否更新成功还须要做进一步推断,为了方便,它能够变种为直接返回是否更新成功,例如以下:

    bool compare_and_swap (int *accum, int *dest, int newval)
    {
        if ( *accum == *dest ) {
            *dest = newval;
            return true;
        }
        return false;
    }
   
4、CAS 在各个平台下的实现
 
4.1 Linux GCC 支持的 CAS
GCC4.1+版本号中支持CAS的原子操作(完整的原子操作可參看 GCC Atomic Builtins)

   1》: bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
   2》: type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
4.2  Windows支持的CAS
在Windows下。你能够使用以下的Windows API来完毕CAS:(完整的Windows原子操作可參看MSDN的InterLocked Functions)
   1: InterlockedCompareExchange ( __inout LONG volatile *Target, __in LONG Exchange, __in LONG Comperand);
4.3  C++ 11支持的CAS
C++11中的STL中的atomic类的函数能够让你跨平台。(完整的C++11的原子操作可參看 Atomic Operation Library)
   template< class T >
   bool atomic_compare_exchange_weak( std::atomic<T>* obj,
                                      T* expected, T desired );
   template< class T >
   bool atomic_compare_exchange_weak( volatile std::atomic<T>* obj,
                                      T* expected, T desired );

5、Fetch And Add


6、gcc从4.1.2提供了__sync_*系列的built-in函数,用于提供加减和逻辑运算的原子操作。

其声明如下:
type __sync_fetch_and_add (type *ptr, type value, ...)
type __sync_fetch_and_sub (type *ptr, type value, ...)
type __sync_fetch_and_or (type *ptr, type value, ...)
type __sync_fetch_and_and (type *ptr, type value, ...)
type __sync_fetch_and_xor (type *ptr, type value, ...)
type __sync_fetch_and_nand (type *ptr, type value, ...)

type __sync_add_and_fetch (type *ptr, type value, ...)
type __sync_sub_and_fetch (type *ptr, type value, ...)
type __sync_or_and_fetch (type *ptr, type value, ...)
type __sync_and_and_fetch (type *ptr, type value, ...)
type __sync_xor_and_fetch (type *ptr, type value, ...)
type __sync_nand_and_fetch (type *ptr, type value, ...)
这两组函数的区别在于第一组返回更新前的值,第二组返回更新后的值。

bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
这两个函数提供原子的比较和交换,如果*ptr == oldval,就将newval写入*ptr,
第一个函数在相等并写入的情况下返回true.
第二个函数在返回操作之前的值。    

7、CAS无锁操作可能产生的问题
7.1、CAS原语有三个参数,内存地址,期望值,新值。如果内存地址的值==期望值,表示该值未修改,此时可以修改成新值。否则表示修改失败,返回false,由用户决定后续操作

7.2、缺点:

使用CAS会造成ABA问题

ABA 问题
thread1意图对val=1进行操作变成2,cas(*val,1,2)。
thread1先读取val=1;thread1被抢占,让thread2运行。
thread2 修改val=3,又修改回1。
thread1继续执行,发现期望值与“原值”(其实被修改过了)相同,完成CAS操作。

解决方案
ABAʹ:添加额外的标记用来指示是否被修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值