当前位置: > > > > 更改地图链接并发安全吗?
更改地图链接并发安全吗?
来源:stackoverflow
2024-04-19 17:54:34
0浏览
收藏
大家好,我们又见面了啊~本文《更改地图链接并发安全吗?》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~
问题内容
您知道吗,在并发环境中将映射变量链接更改为另一个链接是否安全?
一个示例是,在一个 goroutine 中将映射 data 替换为新映射,并在另一个 goroutine 中读取其中的元素:
import (
"fmt"
"math/rand"
"strconv"
"testing"
"time"
)
func TestMap(t *testing.T) {
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
data := fill(r1.Intn(100))
timer := time.NewTimer(10 * time.Second)
go func() {
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
for {
select {
case <-timer.C:
return
default:
}
p := r1.Intn(100)
v := fill(p)
data = v
fmt.Println("_p=" + strconv.Itoa(p))
}
}()
for range []int{1, 2, 3, 4, 5, 6, 7, 8} {
go func() {
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
for {
select {
case <-timer.C:
return
default:
}
n := r1.Intn(100)
s := strconv.Itoa(n)
fmt.Println(data[s])
}
}()
}
<-timer.C
}
func fill(postfix int) map[string][]string {
m := make(map[string][]string)
for i := 0; i < 100; i++ {
s := strconv.Itoa(i)
m[s] = []string{s + "_" + strconv.Itoa(postfix)}
}
return m
}
解决方案
当然不安全。没有变量(包括映射)对于并发读写是安全的。
你的一个 goroutine 写入 data,另一个 goroutine 读取它。使用 go test -race 运行测试还会报告数据争用:
testing.go:954: race detected during execution of test
多个goroutine中必须同步读写data变量。
事实并非如此,使用sync.mutex来锁定它,并在更新数据时解锁它。
终于介绍完啦!小伙伴们,这篇关于《更改地图链接并发安全吗?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~米云公众号也会发布Golang相关知识,快来关注吧!
