英文:
Is this a race condition in go
问题
func main() {
m := map[string]int{
"foo": 42,
"bar": 1337,
}
go func() {
time.Sleep(1 * time.Second)
tmp := map[string]int{
"foo": 44,
"bar": 1339,
}
m = tmp
}()
for {
val := m["foo"]
fmt.Println(val)
}
}
我在许多包中看到了这段代码。
为什么这不被视为竞态条件?
go run -race .
没有报错。
英文:
func main() {
m := map[string]int{
"foo": 42,
"bar": 1337,
}
go func() {
time.Sleep(1 * time.Second)
tmp := map[string]int{
"foo": 44,
"bar": 1339,
}
m = tmp
}()
for {
val := m["foo"]
fmt.Println(val)
}
}
I saw this in many packages.
Why this is not considered as a race condition?
go run -race .
giving no error.
答案1
得分: 3
如@Volker所指出的,这是一个数据竞争。由于只有一个写入操作,很难检测到。这里是一个修改后的示例,可以更容易地触发数据竞争错误:
package main
import (
"fmt"
"time"
)
func main() {
m := map[string]int{
"foo": 42,
"bar": 1337,
}
done := make(chan any)
go func() {
for i := 0; i < 100; i++ {
time.Sleep(time.Microsecond)
tmp := map[string]int{
"foo": 44,
"bar": 1339,
}
m = tmp
}
close(done)
}()
for {
select {
case <-done:
return
default:
val := m["foo"]
fmt.Println(val)
}
}
}
英文:
As pointed out by @Volker, this is a data race. And since there is only one write, it's hard to be detected. Here is a modified demo to make it easy to trigger the data race error:
package main
import (
"fmt"
"time"
)
func main() {
m := map[string]int{
"foo": 42,
"bar": 1337,
}
done := make(chan any)
go func() {
for i := 0; i < 100; i++ {
time.Sleep(time.Microsecond)
tmp := map[string]int{
"foo": 44,
"bar": 1339,
}
m = tmp
}
close(done)
}()
for {
select {
case <-done:
return
default:
val := m["foo"]
fmt.Println(val)
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论