golang并发同步问题

时间:2015-12-28 15:22:05

标签: go concurrency channel goroutine

使用goroutines时遇到同步问题。我的程序输出不可预测的结果。我检查了文档,对于无缓冲的通道,无法检查是否所有的msg都已处理完毕。我将问题简化为这个仍然可以解释问题的小代码。显然这不是Golang的问题,而是我的代码。显然我没有使用正确的并发模式。

问题是如何解决这个问题。如果可能的话,我既不想关闭频道也不想停止蜂巢goroutine。它认为如果我可以假设一旦所有蜜蜂goroutine完成蜂巢现在也完成了(这就是我尝试使用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

1 个答案:

答案 0 :(得分:4)

您永远不会等待“hive”循环完成,因此有时您会在完成之前打印count值。

最简单的方法是使用WaitGroup来指示关闭通道的时间,并在for range循环上阻止main

go func() {
    wg.Wait()
    close(c)
}()

for out := range c {
    count += out
}

http://play.golang.org/p/jK24dtG2je