聊聊golang中的鎖

2021-09-29 10:02:25 字數 1734 閱讀 6834

學習過作業系統的都知道程式有臨界區這個概念,臨界區就是程式片段訪問臨界資源的那部分**,臨界區同一時刻只能有乙個執行緒進行訪問,其他執行緒需要訪問的話必須等待資源空閒。那麼一般程式語言都會使用鎖來進行臨界區訪問控制。

golang主要有兩種鎖:互斥鎖讀寫鎖

互斥鎖mutex:

mutex 用於提供一種加鎖機制(locking mechanism),保證同一時刻只有乙個goroutine在臨界區執行。

互斥鎖定義如下:

var mutex sync.mutex;
它用於對goroutine進行加鎖和解鎖,lock()之後其他goroutine便不能對其鎖定的區進行操作。

看下面**:

package main

import (

"fmt"

"time"

)func main() ()

time.sleep(time.second)

fmt.println(x)

}

一般它都會列印1。

但是有沒有這種可能:

併發執行過程**現時間延誤,例如我goroutine1執行完後x=1,goroutine2拿到的x並不是0,而是goroutine1已經執行好的x = 1,那麼x再次自加,就會返回2。

這就是由於多個goroutine對x進行操作之後可能產生的錯誤,沒有進行臨界區訪問控制。

加鎖:

package main

import (

"fmt"

"sync"

"time"

)func main() ()

time.sleep(time.second)

fmt.println(x)

}

這樣的話就是執行緒安全了,只有乙個goroutine對x進行操作。

讀寫鎖rwmutex:

讀寫鎖實際是一種特殊的自旋鎖,它把對共享資源的訪問者劃分成讀者和寫者,讀者只對共享資源進行讀訪問,寫者則需要對共享資源進行寫操作。這種鎖相對於自旋鎖而言,能提高併發性,因為在多處理器系統中,它允許同時有多個讀者來訪問共享資源,最大可能的讀者數為實際的邏輯cpu數。寫者是排他性的,乙個讀寫鎖同時只能有乙個寫者或多個讀者(與cpu數相關),但不能同時既有讀者又有寫者。

總的來說,就是寫的時候不允許讀和多個寫,讀的時候不允許寫但是允許多個讀,讀和寫不能同時進行。

func (*rwmutex) lock

func (*rwmutex) unlock

func (*rwmutex) rlock

func (*rwmutex) runlock

lock方法將rw鎖定為寫入狀態,禁止其他執行緒讀取或者寫入。

unlock方法解除rw的寫入鎖狀態,如果m未加寫入鎖會導致執行時錯誤。

rlock方法將rw鎖定為讀取狀態,禁止其他執行緒寫入,但不禁止讀取。

runlock方法解除rw的讀取鎖狀態,如果m未加讀取鎖會導致執行時錯誤。

func read() 

func write()

func main() ()

time.sleep(2 * time.second)

}

執行結果: 

golang的goroutine 同步 鎖

goroutine 協程 程序 執行緒?程序,執行緒都是os層面的系統排程方式。協程是使用者層面的呼叫方式,利用更少的資源進行切換,而不需要system call。但協程是呼叫的os的執行緒在執行。當乙個函式為def abc 時,使用go abc 即為開乙個協程去呼叫這個函式 goroutine在遇...

golang 併發鎖的陷阱

package main import sync strconv fmt type node struct var cache node func main cache 1 node wg sync.waitgroup for i 0 i 10000 i i wg.wait fmt.println ...

golang 自旋鎖的實現

cas演算法 compare and swap cas演算法是一種有名的無鎖演算法。無鎖程式設計,即不使用鎖的情況下實現多執行緒之間的變數同步,也就是在沒有執行緒被阻塞的情況下實現變數的同步,所以也叫非阻塞同步 non blocking synchronization cas演算法涉及到三個運算元 ...