【go】golang中鎖的用法-互斥鎖

互斥鎖

  1. 解釋:互斥鎖,保證同一時刻只有 1 個 goroutine 訪問共享資源,比如多個協程同時修改同一個文件,同一時刻只能同一個協程進行修改
  2. 使用方法
// 定義一個互斥鎖
// var 變量名 互斥鎖類型
var guardMutex sync.Mutex

//上鎖
guardMutex.Lock()

// 釋放鎖
guardMutex.Unlock()
  1. 實際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
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章