【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
}

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