golang互斥鎖 sync.Mutex
先看一段代碼
package main
import (
"fmt"
"sync"
)
var x int
var wg sync.WaitGroup
func f1() {
for i := 0; i < 20000; i++ {
x++
}
wg.Done()
}
func main() {
wg.Add(2)
go f1()
go f1()
wg.Wait()
fmt.Println(x)
}
E:\go\src\learngolang\00test>00test.exe
38289
E:\go\src\learngolang\00test>00test.exe
39420
E:\go\src\learngolang\00test>00test.exe
37269
我們執(zhí)行幾次看到其實(shí)返回的x值是不固定的,因?yàn)?,兩個(gè)goroutine并行執(zhí)行,都會對x的值做出讀寫操作,導(dǎo)致了換亂。這時(shí)我們可以對x加一個(gè)互斥鎖,保證同時(shí)只有一個(gè)goroutine可以訪問 共享變量(臨界區(qū))。
var mutex sync.Mutex
修改一下 f1()
func f1() {
for i := 0; i < 20000; i++ {
mutex.Lock() // 所在goroutine獲得互斥鎖之后,會阻塞其他goroutine對臨界區(qū)的訪問
x++ // Lock與Unlock直接的代碼段叫臨界區(qū),慣例來說,被保護(hù)的變量應(yīng)該再Lock()之后立即聲明
mutex.Unlock() // goroutine在結(jié)束后釋放鎖是必要的,無論以哪條路徑通過函數(shù)都需要釋放,即使是在錯(cuò)誤路徑中,也要記得釋放。
}
wg.Done()
}
再執(zhí)行幾下看看
E:\go\src\learngolang\00test>go build
E:\go\src\learngolang\00test>00test.exe
40000
E:\go\src\learngolang\00test>00test.exe
40000
E:\go\src\learngolang\00test>00test.exe
40000