詳解Golang互斥鎖內部實現

2022-09-24 18:27:11 字數 2049 閱讀 5800

go語言提供了一種開箱即用的共享資源的方式,互斥鎖(sync.mutex), sync.mutex的零值表示乙個沒有被鎖的,可以直接使用的,乙個goroutine獲得互斥鎖後其他的goroutine只能等到這個gorutine釋放該互斥鎖,在mutex結構中只公開了兩個函式,分別是lock和unl程式設計客棧ock,在使用互斥鎖的時候非常簡單,本文並不闡述使用。

在使用sync.mutex的時候千萬不要做值拷貝,因為這樣可能會導致鎖失效。當我們開啟我們的ide時候跳到我們的sync.mutex **中會發現它有如下的結構:

type mutex struct

const (

mutexlocked = 1 << iota // 1 互斥鎖是鎖定的

mutexwoken // 2 喚醒鎖

mutexwaitershift = iota // 2 統計阻塞在這個互斥鎖上的goroutine數目需要移位的數值

)上面的state值分別為 0(可用) 1(被鎖) 2~31等待佇列計數

下面是互斥鎖的原始碼,這裡會有四個比較重要的方法需要提前解釋,分別是runtime_canspin,runtime_dospin,runtime_semacquiremutex,runtime_semrelease,

1、runtime_canspin:比較保守的自旋,golang中自旋鎖並不會一直自旋下去,在runtime包中runtime_canspin方法做了一些限制, 傳遞過來的iter大等於4或者cpu核數小等於1,最大邏輯處理器大於1,至少有個本地的p佇列,並且本地的p佇列可執行g隊列為空。

//go:linkname sync_runtime_canspin sync.runtime_canspin

func sync_runtime_canspin(i int) bool

if p := getg().m.p.ptr(); !runqempty(p)

return true

}2、 runtime_dospin:會呼叫procyield函式,該函式也是組合語言實現。函式內部迴圈呼叫pause指令。pause指令什麼都不做,但是會消耗cpu時間,在執行pause指令時,cpu不會對它做不必要的優化。

//go:linkname sync_runtime_dospin sync.runtime_dospin

func sync_runtime_dospin()

3、runtime_semacquiremutex:

//go:linkname sync_runtime_semacquiremutex sync.runtime_semacquiremutex

func sync_runtime_semacquiremutex(addr *uint32)

4、runtime_semrelease:

//go:linkname sync_runtime_semrelease sync.runtime_semrelease

func sync_runtime_semrelease(addr *uint32)

mutex的lock函式定義如下

func (m *mutex) lock()

//成功獲取返回

return

} awoke := false //循程式設計客棧環標記

iter程式設計客棧 := 0 //迴圈計數器

for

//進入自旋狀態

runtime_dospin()

iter++

continue

} //沒有獲取到鎖,當前g進入gwaitting狀態

new = old + 1<>mutexwaitershift == 0 || old&(mutexlocked|mutexwoken) != 0

// 減少等待次數,新增清除標記

new (old - 1<

互斥鎖無衝突是最簡單的情況了,有衝突時,首先進行自旋,,因為大多數的mutex保護的**段都很短,經過短暫的自旋就可以獲得;如果自旋等待無果,就只好通過訊號量來讓當前goroutine進入gwaitting狀態。

本文標題: 詳解golang互斥鎖內部實現

本文位址:

golang互斥鎖跟讀寫鎖

golang中sync包實現了兩種鎖mutex 互斥鎖 和rwmutex 讀寫鎖 其中rwmutex是基於mutex實現的,唯讀鎖的實現使用類似引用計數器的功能 1 互斥鎖 其中mutex為互斥鎖,lock 加鎖,unlock 解鎖,使用lock 加鎖後,便不能再次對其進行加鎖,直到利用unlock...

Golang 併發之互斥鎖

當多個goroutine同時訪問乙個資源的時候需要加上互斥鎖防止出錯。互斥鎖能保證同時只有乙個goroutine訪問共享資源。go語言中使用sync包的mutex型別詩選互斥鎖。go語言中對 mutex 的定義 a mutex is a mutual exclusion lock.the zero ...

Golang 原子操作與互斥鎖

先來看乙個 package main import fmt runtime sync var counter int32 wg sync.waitgroup func main func addcounter whoami string final counter is 2 首先這個程式是起了兩個 ...