鉴于以下内容:
package main
import (
"fmt"
"sync"
)
func main() {
n := 100
var wg sync.WaitGroup
wg.Add(n)
x := 0
for i := 0; i < n; i++ {
go func() {
defer wg.Done()
x++
}()
}
wg.Wait()
fmt.Println(n, x)
}
我希望x
在最后打印时始终达到100
,但有时会打印到95
一样低。我在这里缺少什么?
答案 0 :(得分:6)
x
上有一场比赛。一个解决方法是使用互斥锁保护x
:
var mu sync.Mutex
var wg sync.WaitGroup
wg.Add(n)
x := 0
for i := 0; i < n; i++ {
go func() {
defer wg.Done()
mu.Lock()
x++
mu.Unlock()
}()
}
wg.Wait()
fmt.Println(n, x)
我建议只要在Go程序中发现有多个goroutine的东西就会运行race detector。
答案 1 :(得分:1)
使用sync.atomic方法以原子方式访问x。
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
n := 100
var wg sync.WaitGroup
wg.Add(n)
var x int32
for i := 0; i < n; i++ {
go func() {
defer wg.Done()
atomic.AddInt32(&x, 1)
}()
}
wg.Wait()
fmt.Println(n, x)
}