鎖
互斥鎖
- 解釋:互斥鎖,保證同一時刻只有 1 個 goroutine 訪問共享資源,比如多個協程同時修改同一個檔案,同一時刻只能同一個協程進行修改
- 使用方法
// 定義一個互斥鎖
// var 變數名 互斥鎖型別
var guardMutex sync.Mutex
//上鎖
guardMutex.Lock()
// 釋放鎖
guardMutex.Unlock()
- 實際demo
package main
import (
"fmt"
"sync"
)
// 不帶互斥鎖
type SumStruct struct {
value int
wg sync.WaitGroup
}
// 帶互斥鎖的
type CountStruct struct {
value int
wg sync.WaitGroup // 等待組
mu sync.Mutex // 互斥鎖
}
func main() {
var sum int
// 沒有互斥鎖的
// sum = sumNoMutex()
// 使用互斥鎖的
sum = sumUseMutex()
fmt.Printf("最終sum的值 = %d\n", sum)
}
// 示例1:沒有互斥鎖,多個協程對同一個值進行++,計算最後的結果,最終可能不是500
func sumNoMutex() int {
sumStruct := SumStruct{}
// 啟動5個協程
sumStruct.wg.Add(5)
for i := 1; i <= 5; i++ {
go func(w *sync.WaitGroup) {
defer w.Done()
for j := 0; j < 100; j++ {
sumStruct.value = sumStruct.value + 1
}
}(&sumStruct.wg)
}
// 等待5個協程全部執行完成
sumStruct.wg.Wait()
return sumStruct.value
}
// 示例1:互斥鎖 sync.Mutex
func sumUseMutex() int {
countStruct := CountStruct{}
countStruct.wg.Add(5)
// 啟動5個協程,每個協程裡邊進行+1操作
for i := 0; i < 5; i++ {
go func(cs *CountStruct) {
defer cs.wg.Done()
for j := 0; j < 1000; j++ {
cs.add()
}
}(&countStruct)
}
// 等待協程全部執行完成
countStruct.wg.Wait()
sum := countStruct.getValue()
return sum
}
// +1 計算
func (c *CountStruct) add() {
// 使用互斥鎖,保證同一時刻只有1個協程可修改這個變數
c.mu.Lock()
defer c.mu.Unlock()
c.value++
}
// 獲取最後的值
func (c *CountStruct) getValue() int {
c.mu.Lock()
defer c.mu.Unlock()
return c.value
}