0
点赞
收藏
分享

微信扫一扫

golang map 如果value值存的是对象指针,多协程修改值,会造成读写并发异常吗?

秦瑟读书 2022-11-22 阅读 91


先贴答案: 不会

golang中map的三个结论:

  1. 多协程同时只写入,会发生 concurrent map write 异常,必须加锁
  2. 多协程同时写入读取,写入加锁,读取不加,不会异常,只是不确保读取的数据是否脏
  3. 多协程同时只读取,加锁数据干净,不加锁数据可能脏

package main

import (
"fmt"
"runtime"
"sync"
)



func main() {
runtime.GOMAXPROCS(runtime.NumCPU())


var m = make(map[string]*int,0)
var l = & sync.RWMutex{}
var a = 5
m ["a"] = &a
var wg = sync.WaitGroup{}
for i:=0;i<10000;i++ {
wg.Add(1)
go func(wg *sync.WaitGroup, m *map[string]*int,l *sync.RWMutex) {
defer wg.Done()

writeM(m,l)
}(&wg, &m, l)
}
for i:=0;i<10000;i++ {
wg.Add(1)
go func(wg *sync.WaitGroup, m *map[string]*int,l *sync.RWMutex) {
defer wg.Done()

readM(m,l)
}(&wg, &m, l)
}
for i:=0;i<10000;i++ {
wg.Add(1)
go func(wg *sync.WaitGroup, m *map[string]*int,l *sync.RWMutex) {
defer wg.Done()

changeA(&a)
}(&wg, &m, l)
}

wg.Wait()
}

func readM(m *map[string]*int,l *sync.RWMutex){
l.RLock()
defer l.RUnlock()
a := (*m)["a"]
fmt.Println(a)
}

func writeM(m *map[string]*int,l *sync.RWMutex) {
l.Lock()
defer l.Unlock()
var tmp = 7
(*m)["a"] = &tmp
}

func changeA(a *int){
*a++
}

如代码所示,1万协程读,1万协程写,1万协程无锁修改其value指针对象的值,并不会因为造成读写崩溃。
map的读写场景:

var m map[string]*string
tmp := "3"
// 写
go func(){
m["5"] = &tmp
}
// 读
go func(){
_ = m["5"]
}()
// 此不属于写,是map安全的操作,无须加map 锁
*tmp = "4"


举报

相关推荐

0 条评论