无锁编程

    无锁编程,即不使用锁的状况下实现多线程之间的变量同步,也就是在没有线程被阻塞的状况下实现变量的同步,因此也叫非阻塞同步(Non-blocking Synchronization)。
实现非阻塞同步的方案称为“无锁编程算法”(  Non-blocking algorithm)。
    多线程编程条件下,多个线程须要对同一共享变量写操做时,通常使用互斥锁来解决竞争问题,以下:
1 extern int g_var;
2 
3 mutex_lock;
4 g_var ++;
5 mutex_unlock;

使用锁会致使其余线程block,使用不当还有可能形成死锁,如下介绍无锁编程相关概念。算法

一、LL/SC操做编程

MIPS等RISC cpu支持LL(Load Link)/SC(Store Conditional)操做,主要原理为:多线程

1. LL t0, lock_key
# LL从内存中读取数据到寄存器中,实现接下来的 RMW(Read-Modify-Write) 操做中的Read。处理器会记住 LL 指令的此次操做(会在 CPU 的寄存器中设置一个不可见的 bit 位),同时 LL 指令读取的地址lock_key也会保存在处理器的寄存器中。

2. SC t0, lock_key
# SC 指令的功能是向内存中写入一个字,以完成前面的 RMW 操做中Write。会检查上次 LL 指令执行后的 RMW 操做是不是原子操做(即不存在其它对这个地址的操做),若是是原子操做,则 t0 的值将会被更新至内存中,同时 t0 的值也会变为1,表示操做成功;反之,若是 RMW 的操做不是原子操做(即存在其它对这个地址的访问冲突),则 t 的值不会被更新至内存中,且 t 的值也会变为0,表示操做失败。

SC 指令执行失败的缘由有两种:spa

(1)在 LL/SC 操做序列的过程当中,发生了一个异常(或中断),这些异常(或中断)可能会打乱 RMW 操做的原子性。线程

(2)在多核处理器中,一个核在进行 RMW 操做时,别的核试图对一样的地址也进行操做,这会致使 SC 指令执行的失败。code

经过CPU支持的LL/SC操做,能够实现无锁对变量进行修改。blog

 

二、CAS操做ip

CAS(Compare And Swap): It compares the contents of a memory location to a given value and, only if they are the same, modifies the contents of that memory location to a given new value.内存

在 x86 下的指令CMPXCHG实现了CAS,前置LOCK既能够达到原子性操做, CAS 伪代码:get

1 int compare_and_swap(int* reg, int oldval, int newval)
2 {
3   ATOMIC();
4   int old_reg_val = *reg;
5   if (old_reg_val == oldval)
6      *reg = newval;
7   END_ATOMIC();
8   return old_reg_val;
9 }

当寄存器中的值old_reg_val等于oldval时,才更新寄存器的值。

相关文章
相关标签/搜索