packagemainimport ("fmt""sync")var total intvar wg sync.WaitGroup// Inc increments the counter for the given key.funcinc(num int) { total += num wg.Done()}// Value returns the current value of the counter for the given key.funcgetValue() int {return total}funcmain() {for i :=1; i <=1000; i++ { wg.Add(1)goinc(i) } wg.Wait() fmt.Println(getValue())}
可以試著加上 --race 來偵測。
執行: go run --race app.go
解決方法有三個
1.runtime.GOMAXPROCS(1)
設定 CPU 只用一顆執行程式
2.使用 sync lock 與 unlock
packagemainimport ("fmt""sync")var total intvar wg sync.WaitGroupvar mu sync.Mutex// Inc increments the counter for the given key.funcinc(num int) { mu.Lock()defer mu.Unlock() total += num wg.Done()}// Value returns the current value of the counter for the given key.funcgetValue() int {return total}funcmain() {for i :=1; i <=1000; i++ { wg.Add(1)goinc(i) } wg.Wait() fmt.Println(getValue())}
3.使用 sync/atomic
packagemainimport ("fmt""sync""sync/atomic")var total uint64var wg sync.WaitGroupfuncinc(num uint64) { atomic.AddUint64(&total, num) wg.Done()}// Value returns the current value of the counter for the given key.funcgetValue() uint64 {return atomic.LoadUint64(&total)}funcmain() {for i :=uint64(1); i <=1000; i++ { wg.Add(1)goinc(i) } wg.Wait() fmt.Println(getValue())}