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回答

ccmouse

2019-06-26

map始终是能够访问的。没有解锁的情况下,我们是拿不到这个mutex而已。我们的代码就要人为保证对map的访问都必须有mutex保护。像后面Print那里没有保护,就可能出问题。

一个解决方法是封装,我们定义一个结构,让map作为一个private变量,然后保证访问这个map的代码都受到mutex保护。

更推荐的是使用sync.Map,见https://colobu.com/2017/07/11/dive-into-sync-Map/

2
1
残天一月
非常感谢!
2019-07-03
共1条回复

Google资深工程师深度讲解Go语言 由浅入深掌握Go语言

语法+分布式爬虫实战 为转型工程师量身打造

5995 学习 · 1909 问题

查看课程