【发布时间】:2022-01-22 14:00:19
【问题描述】:
感谢您在这个问题上帮助我。
据我所知,在 golang 中 map 是非线程安全的,但 chan 是线程安全的。但是如果我使用 chan 作为 map 的值呢?这个map 会成为线程安全的吗?
我写了一个简单的测试(不知道这是否是正确的证明方法)如下所示,并在没有concurrent map read/write error的情况下运行它大约30次。这是否意味着线程安全chan使非-线程安全map线程安全?
map 是否成为线程安全的,谁能为我解释得更深入一点?谢谢!
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
te := &testS{
name: "test",
val: map[string]chan int{
"a": make(chan int, 10000000),
},
}
for i := 0; i < 50000; i++ {
te.val["a"] <- i
}
for i := 0; i < 30000; i++ {
go write(te)
go read(te)
}
for {
fmt.Println("Waiting")
time.Sleep(time.Second)
}
}
func read(t *testS) {
time.Sleep(time.Duration(rand.Intn(3)) * time.Second)
<-t.val["a"]
fmt.Println("read")
}
func write(t *testS) {
time.Sleep(time.Duration(rand.Intn(3)) * time.Second)
t.val["a"] <- 1
fmt.Println("write")
}
type testS struct {
name string
val map[string]chan int
}
【问题讨论】:
-
"但是如果我使用 chan 作为映射的值呢?这个映射会成为线程安全的吗?" -- 不会。
-
请注意,只读映射对于并发使用是安全的,无论元素类型如何。您上面的示例仅从地图中读取。因此不会发生数据竞争错误。
标签: dictionary go concurrency thread-safety channel