CAS是个什么玩意?

本文介绍了在多线程环境下,如何从传统的互斥锁(悲观锁)过渡到CAS(Compare And Swap)操作,以实现更高效的资源同步。CAS是一种乐观锁策略,适用于读多写少的场景,避免了线程阻塞。通过举例说明了CAS的工作原理,并指出其在x86和ARM架构下的原子性保证。同时,讨论了自旋等待在处理竞争条件时的角色,以及可能存在的ABA问题和活锁风险。
摘要由CSDN通过智能技术生成

背景

现在有多个线程想要操作同一资源对象,很多人一上来就会选择互斥锁,但是有一个问题就是:互斥锁的同步方式是悲观的。所谓悲观就是,操作系统会悲观的认为:如果不严格同步线程调用,那么一定会产生异常,所以互斥锁将会将资源进行锁定,直供一个线程调用而阻塞其他的线程,这样的同步机制叫做悲观锁。

但是悲观锁不是万能的,如果在大量调用都是读操作的情况下,那么就没有必要在每次调用的时候都锁定资源。或者在一些情况下,同步代码的耗时远远小于线程切换的耗时,现在选择悲观锁的话就显得本末倒置了。

这是就提出了一个问题,能否不锁定资源,也能同步线程。

CAS

CAS(Compare And Swap)比较和交换。例如,资源对象有着0、1两个状态,现在有两个线程A、B去读取资源对象的状态。当资源对象的状态值为0的一瞬间,ab线程都读到了,此时这两条线程认为资源对象的状态值为0,于是它们各自将会生成两个值,Old Value代表之前读到的资源对象的状态值,New Value代表想要更新资源对象的状态值。
在这里插入图片描述
此时A、B线程都会去争抢着去修改资源对象的状态值,然后占用它。假设A线程率先获得了时间片,它将old value与资源对象的状态值进行compare发现一致,于是将资源对象的值swap为new value = 1。但是B线程发现此时old value和资源对象的值不一致,所以就放弃了swap操作。
在这里插入图片描述

但是在实际应用中,通常会使B线程进行自旋(自旋,就是使其不断地重试CAS操作),通过配置自旋的次数来防止死循环。

需要注意的是compare和swap这两个动作必须“被绑定”,在同时只能有一条线程进行操作,即CAS是原子性的。

CAS原子性:

  1. x86架构下,通过cmpxchg指令支持CAS原子性
  2. ARM架构下,通过LL/SC来实现CAS的原子性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值