简介
多个协程会操作一个特定资源,就会出现意想不到的错误类比脏读幻读等,所以我们使用互斥锁,
一个协程使用特定资源的时候进行锁定,用完解锁,
再让其他协程使用,所以其他协程想使用此资源,必须自己给资源解锁或等待正在使用的协程解锁
在代码中就是锁定一段代码,代码里面有资源。
注意
- 在一个 goroutine 获得 Mutex 后,其他 goroutine 只能等到这个 goroutine 释放该 Mutex
- 使用 Lock() 加锁后,不能再继续对其加锁,直到利用 Unlock() 解锁后才能再加锁
- 在 Lock() 之前使用 Unlock() 会导致 panic 异常
- 已经锁定的 Mutex 并不与特定的 goroutine 相关联,这样可以利用一个 goroutine 对其加锁,再利用其他 goroutine 对其解锁
- 在同一个 goroutine 中的 Mutex 解锁之前再次进行加锁,会导致死锁
- 适用于读写不确定,并且只有一个读或者写的场景
参考
https://www.cnblogs.com/shockerli/p/golang-pkg-mutex.html
代码
package main
import (
"fmt"
"sync"
"time"
)
func ccc(i int)(){
mutex.Lock()
fmt.Println("Lock:", i)
time.Sleep(time.Second)
fmt.Println("Unlock:", i)
mutex.Unlock()
defer wait.Done()
}
var mutex sync.Mutex
var wait = sync.WaitGroup{}
func main() {
fmt.Println("互斥锁")
mutex.Lock()
for i := 1; i <= 3; i++ {
wait.Add(1)
go ccc(i)
}
mutex.Unlock()
wait.Wait()
}
// 互斥锁锁定一个资源
// 其他的协程无法进行操作此段的资源 其他的协程都选择等待此段锁代码的结束
// 这个资源已经被当前的协程进行锁定,其他的协程也要操作此资源的都要等待
// 锁是表明一段代码中只能同步执行的
// 互斥锁
// Lock: 1
// Unlock: 1
// Lock: 3
// Unlock: 3
// Lock: 2
// Unlock: 2