CAS 是如何将这两个操作进行比较和交换,变成一个原子操作呢?这符合硬件指令集的发展,实际上,我们可以使用同步将这两个操作变成原子的,但是对象就没有所以我们依靠硬件来完成,硬件只能保证一个从外观上需要多次操作的行为只需通过一条处理器指令才能完成。此类指令常用的有:
- 测试并设置(Test-and-Set)
- 获取并增加(Fetch-and-Increment)
- 交换(Swap)
- 比较并交换(Compare-and-Swap)
- 加载链接/条件存储(Load-Linked/Store-Conditional)
-
CPU实现原子指令有2种方式:
通过线程锁定来保证原子性: - 入口锁定其实就是处理器使用了入口锁,所谓入口锁就是使用处理器提供的一个LOCK#信号,当一个处理器在入口上输出这个信号时,其他处理器的请求将被阻塞住,那么该处理设备可以独占共享内存。但是该方法成本很巧。因此有了下面的方法。
- 通过存储锁定来保证原子性:
- 所谓缓存锁定是指内存区域,如果缓存被缓存在处理器的缓存行中,并且在锁定操作期间被锁定,那么当他执行锁定操作写回到内存时,内存不再磁盘上声言LOCK#信号,而是修改内部的内存地址,并允许他的数据库一致性机制来保证操作的原子性,因为数据库一致性机制会同时阻止两个以上内存数据库的内存区域数据(这里和易失性的可见性原理相同) ,当其他CPU回写已被锁定的服务器行的数据时,使服务器行无效。