php小編蘋果在這篇文章中將為您解答一個(gè)常見的問題:“這是Go中的競爭條件嗎?”在編寫并發(fā)程序時(shí),競爭條件是一個(gè)常見的問題,它可能導(dǎo)致數(shù)據(jù)不一致以及其他意想不到的結(jié)果。在Go語言中,我們可以使用互斥鎖、通道等機(jī)制來避免競爭條件的發(fā)生。讓我們一起來探討一下吧!
問題內(nèi)容
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)
}
}
登錄后復(fù)制
我在很多包中都看到了這個(gè)。
為什么這不被視為競爭條件?
go run -race . 沒有錯(cuò)誤。
解決方法
正如@volker 所指出的,這是一場數(shù)據(jù)競賽。而且由于只有一次寫入,因此很難被檢測到。這是一個(gè)修改后的演示,可以輕松觸發(fā)數(shù)據(jù)爭用錯(cuò)誤:
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)
}
}
}
登錄后復(fù)制






