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