Go語言中sync.Mutex的使用方法
背景
多個協(xié)程操作中經(jīng)常出現(xiàn)臟讀寫的情況,這種情況下需要使用互斥鎖,保證在對協(xié)程共享區(qū)域操作的原子性。
如下示例:
啟動了 100個協(xié)程,每個協(xié)程累加 100 次,在沒有臟讀寫的情況下,最后結(jié)果應(yīng)該是 100 * 100 = 10000
package main
import (
"fmt"
"sync"
)
func main() {
var count = 0
var wg sync.WaitGroup
wg.Add(100)
for i :=0; i< 100; i++ {
go func(){
defer wg.Done()
for j := 0; j< 100; j ++ {
count ++
}
}()
}
wg.Wait()
fmt.Println(count)
}
但是實際結(jié)果一直小于 10000

互斥鎖
count ++ 操作, 分為三個步驟
在協(xié)程的共享區(qū)域取出 count 當前值
當前值加一
加一后的值寫回協(xié)程共享區(qū)域
這時需要使用互斥鎖, 來保證對 count++ 的三個操作過程中沒有其他協(xié)程進行讀寫。
Go的Sync 包提供了Mutex, 讀寫互斥的鎖, 來保證只有一個協(xié)程對數(shù)據(jù)進行讀寫操作。 以保證 count++操作的原子性
如下示例:
package main
import (
"fmt"
"sync"
)
func main() {
var count = 0
// 聲明Mutex變量
var mu sync.Mutex
var wg sync.WaitGroup
wg.Add(100)
for i :=0; i< 100; i++ {
go func(){
defer wg.Done()
for j := 0; j< 100; j ++ {
// 添加鎖
mu.Lock()
count ++
// 解鎖
mu.Unlock()
}
}()
}
wg.Wait()
fmt.Println(count)
}
在mu.Lock() 和mu.Unlock() 之間的代碼可以保證在操作只會被一個協(xié)程執(zhí)行。這樣執(zhí)行結(jié)果就是 10000 了

注意
mu.Lock() 和mu.Unlock() 必須成對出現(xiàn),在忘掉 Unlock 的情況下,鎖獲取后永遠不會得到釋放,其他 的線程/協(xié)程會永遠處于阻塞狀態(tài),永遠獲取不到鎖,在忘掉 Lock 的情況下,直接 Unlock 一個未加鎖的 Mutex,會導致程序 panic。
到此這篇關(guān)于Go語言中sync.Mutex的使用方法的文章就介紹到這了,更多相關(guān)Go sync.Mutex內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言中的空值(nil)與零值(zerovalue)區(qū)別詳解
在Go語言中,空值(nil)和零值(zero value)是兩個不同的概念,它們在語義、使用場景以及實際的編程實踐中有著明顯的區(qū)別,理解這兩者的差異對于編寫清晰、健壯的Go代碼至關(guān)重要,需要的朋友可以參考下2024-06-06

