概述
原子(atomic)本意是“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为“不可被中断的一个或一系列操作”,可以保证指令以原子的方式运行,即执行过程不被打断。
对一个整数的操作可以用原子函数,避免使用互斥锁、自旋锁等锁机制带来的线程阻塞、锁竞争、死锁、优先级反转、性能损耗等问题。
linux内核提供了一套原子操作的函数,比如
static inline int atomic_dec_and_test(atomic_t *v)
函数功能:减一后判断为0则返回true,否则false。这里的减一和判断是否为0为一个原子操作。
竟态问题
原子操作的提出主要是为了解决程序运行过程中的竞态问题,以程序中一个共享全局变量的自加操作count++为例,处理器完成这样一个操作需要三个步骤:
1、从内存中读取count变量的值到寄存器中;
2、将寄存器中的值加1;
3、将寄存器中的值写回到内存中。
这个操作也称为RMW(Read-Modify-Write)。现在假设存在两个执行线程同时在对count(count初始值假设为0)执行自加操作,预期的结果应当是两个线程串行地完成了count的自增操作,count最终的值为2;但在并发场景下,处理器的实际执行序列却可能会是下面这个情况:
之所以会产生上面的情况,原因就是RMW操作本身不具备原子性,它可能会被中断打断或者被并行程序产生的数据竞争影响。为了解决这种问题,就需要让RMW操作成为一个原子操作,这需要硬件提供机制来保证。
单处理器系统下的原子操作
在单处理器(Uni-Processor)系统中,处理器的执行流程只会受到中断机制的影响,由于中断只能发生于指令之间,因此能够在单条指令中完成的操作都可以认为是“原子操作”。单处理器系统实现原子操作的方式有两种:
1、提供能完成多步操作的单条指令:这在采用复杂指令集架构的处理器上比较常见,例如x86架构提供的inc指令就可以通过一条指令完成变量的自加操作;
2、关中断:处理器中断关闭后,就可以不间断地执行一系列指令,等所有操作完成后再打开中断。
多处理器系统下的原子操作
在多处理器(Multi-Processor)系统中,面临的并发问题要严峻很多,由于系统中有多个处理器在独立地运行,即使是一条指令执行期间也会受到其它处理器的干扰,导致指令执行结果错误。在不同的处理器体系结构下,硬件提供的原子操作实现机制会存在区别。x86架构通过对总线加锁保证只允许一个处理器访问,ARM架构通过独占内存。
CAS原子操作
Compare And Set(或Compare And Swap),CAS是解决多线程并行情况下使用锁造成性能损耗的一种机制,采用这种无锁的原子操作可以实现线程安全,避免加锁的笨重性。
CAS操作包含三个操作数:内存位置(V)、预期原值(A)、新值(B)。
如果内存位置的值与预期原值相等,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作;最后返回内存位置的值。
CAS是实现自旋锁的基础,CAS 利用 CPU 指令保证了操作的原子性,以达到锁的效果,循环这个指令,直到成功为止。
标签:count,原子,指令,内存,操作,处理器 From: https://www.cnblogs.com/god-of-death/p/17114990.html