0
我在使用goroutines時遇到同步問題。我的程序輸出不可預知的結果。我檢查了文件和無緩衝的頻道,沒有辦法檢查是否所有的信息已經處理。我將這個問題簡化爲這個仍然演示問題的小演示代碼。很明顯,這不是Golang的問題,而是我的代碼。顯然,我沒有使用正確的併發模式。golang併發同步問題
問題是如何解決這個問題。如果可能的話,我不想關閉通道,也不想停止蜂巢門戶。它認爲如果我可以假設一旦所有的蜜蜂程序都完成了,現在蜂巢也完成了(這是我通過使用wg.Wait()來嘗試的)。
package main
import(
"fmt"
"sync"
"time"
)
func main() {
count := int64(0)
c := make(chan int64)
var wg sync.WaitGroup
// bees
for i:=0; i<5000;i++{
wg.Add(1)
go func(in chan int64) {
defer wg.Done()
time.Sleep(100)
in <- 2
}(c)
}
// hive
go func() {
for out := range c {
count += out
}
}()
wg.Wait()
// bang! but why?
fmt.Println(count)
}
// every now and again the program prints out before it is finished
// $ go run pattern1.go
// 10000
// $ go run pattern1.go
// 9998
// $ go run pattern1.go
// 9998
// $ go run pattern1.go
// 10000
// $ go run pattern1.go
// 10000
// $ go run pattern1.go
// 9998
你在你的代碼的數據種族,請運行帶'-race'標誌的代碼(去運行/ build -race)。這將打印出有關數據競賽的信息。 – nussjustin
如果「hive」循環沒有關閉'c',或者插入另一個計數器和同步原語,您無法確定是否已從'c'處理所有值。如果所有的goroutines都完成了,那麼關閉頻道有什麼意義呢? – JimB
-race標誌必須在運行後但在文件名之前。文件名後面的任何內容都會傳遞給您的進程,但-race是一個編譯器標誌。 – nussjustin