mutex并发访问
来源:11-5 传统同步机制

残天一月
2019-06-26
老师您好,这两天在复习mutex和rwmutex的时候,遇到了一个问题不能理解。
package main
import (
"fmt"
"sync"
"time"
)
// 互斥锁
var mutex sync.Mutex
// 互斥锁使用
// 一个map,三个goroutine,两个goroutine往map中写数据,两个从map中读取数据
// 检测在写操作完成之前,能不能读取数据
func Mutex() {
m := make(map[int]int)
// 两个goroutine往map中写数据
for i :=1 ;i <= 2; i++ {
go func(i int) {
mutex.Lock()
m[i] = i
fmt.Printf("goroutine[%d] map locked\n", i)
time.Sleep(10*time.Second)
}(i)
}
time.Sleep(1*time.Second)
for k, v := range m {
fmt.Printf("k : %v, v : %v\n", k, v)
}
}
func main() {
Mutex()
time.Sleep(5*time.Second)
}
按理说,mutex对map加锁之后,在没有解锁的情况下不能不能访问map吗?但我这里还是可以正常读取,结果如下:
goroutine[1] map locked
k : 1, v : 1
这是为什么呢
写回答
1回答
-
map始终是能够访问的。没有解锁的情况下,我们是拿不到这个mutex而已。我们的代码就要人为保证对map的访问都必须有mutex保护。像后面Print那里没有保护,就可能出问题。
一个解决方法是封装,我们定义一个结构,让map作为一个private变量,然后保证访问这个map的代码都受到mutex保护。
更推荐的是使用sync.Map,见https://colobu.com/2017/07/11/dive-into-sync-Map/
212019-07-03
相似问题