無鎖編程

    無鎖編程,即不使用鎖的狀況下實現多線程之間的變量同步,也就是在沒有線程被阻塞的狀況下實現變量的同步,因此也叫非阻塞同步(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時,才更新寄存器的值。

相關文章
相關標籤/搜索