猿问

golang并发同步问题

我在使用 goroutine 时面临同步问题。我的程序输出不可预测的结果。我检查了文档,对于未缓冲的频道,无法检查是否已处理所有消息。我将问题简化为这个仍然演示问题的小演示代码。显然,这不是 Golang 的问题,而是我的代码的问题。显然我没有使用正确的并发模式。


问题是如何解决这个问题。如果可能,我既不想关闭通道也不想停止 hive goroutine。如果我能假设一旦所有的 bee goroutine 都完成了,那么 hive 也已经完成了(这就是我使用 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


jeck猫
浏览 172回答 1
1回答

有只小跳蛙

您永远不会等待“hive”循环完成,因此有时您会count在完成之前打印该值。最简单的方法是使用 WaitGroup 来通知何时关闭通道,并main在 for range 循环中阻塞:go func() {&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; close(c)}()for out := range c {&nbsp; &nbsp; count += out}http://play.golang.org/p/jK24dtG2je
随时随地看视频慕课网APP

相关分类

Go
我要回答