Golang sync.Mutex包——互斥鎖
阿新 • • 發佈:2022-01-19
1、概述
Mutex 是一個互斥鎖,可以建立為其他結構體的欄位;零值為解鎖狀態。Mutex 型別的鎖和執行緒無關,可以由不同的執行緒加鎖和解鎖。
type Mutex struct { state int32 sema uint32 }
2、方法
Mutex是一個互斥鎖,可以建立為其他結構體的欄位;零值為解鎖狀態。Mutex型別的鎖和執行緒無關,可以由不同的執行緒加鎖和解鎖。
Lock
func (m *Mutex) Lock()
Lock方法鎖住m,如果m已經加鎖,則阻塞直到m解鎖。
Unlock
func (m *Mutex) Unlock()
Unlock方法解鎖m,如果m未加鎖會導致執行時錯誤。鎖和協程無關,可以由不同的協程加鎖和解鎖。
注意:
- 在一個 goroutine 獲得 Mutex 後,其他 goroutine 只能等到這個 goroutine 釋放該 Mutex
- 使用 Lock() 加鎖後,不能再繼續對其加鎖,直到利用 Unlock() 解鎖後才能再加鎖
- 在 Lock() 之前使用 Unlock() 會導致 panic 異常
- 已經鎖定的 Mutex 並不與特定的 goroutine 相關聯,這樣可以利用一個 goroutine 對其加鎖,再利用其他 goroutine 對其解鎖
- 在同一個 goroutine 中的 Mutex 解鎖之前再次進行加鎖,會導致死鎖
- 適用於讀寫不確定,並且只有一個讀或者寫的場景
3、示例
示例一:
var mutex sync.Mutex //互斥鎖 func printer(str string){ mutex.Lock() //加鎖 defer mutex.Unlock() //解鎖 for _,ch:=range str{ fmt.Printf("%c",ch) time.Sleep(time.Millisecond*300) } } func user1(){ printer("hello ") } func user2(){ printer("world") } func main() { go user1() go user2() for { ; } }
輸出:
hello world
示例二:
package main import ( "fmt" "sync" "time" ) func main() { var mutex sync.Mutex wait := sync.WaitGroup{} fmt.Println("Locked") mutex.Lock() for i := 1; i <= 3; i++ { wait.Add(1) go func(i int) { fmt.Println("Not lock:", i) mutex.Lock() fmt.Println("Lock:", i) time.Sleep(time.Second) fmt.Println("Unlock:", i) mutex.Unlock() defer wait.Done() }(i) } time.Sleep(time.Second) fmt.Println("Unlocked") mutex.Unlock() wait.Wait() }
輸出:
Locked Not lock: 3 Not lock: 2 Not lock: 1 Unlocked Lock: 3 Unlock: 3 Lock: 2 Unlock: 2 Lock: 1 Unlock: 1
4、總結
互斥鎖相互排斥,誰搶到鎖誰執行。
參考:https://shockerli.net/post/golang-pkg-mutex/
參考:https://blog.csdn.net/weixin_43851310/article/details/87890645