使用golang频道。 GETTING"所有goroutines都睡着了 - 僵局!"

时间:2016-09-19 14:51:52

标签: go goroutine

iam目前正在玩例程,频道和sync.WaitGroup。我知道waitgroup用于等待所有的例程根据天气wg完成.Done()被调用足够的时间来取消wg.Add()中设置的值。 我写了一小段代码试图在golang操场上测试它。显示如下

var channel chan int
var wg sync.WaitGroup


func main() {

  channel := make(chan int)
  mynums := []int{1,2,3,4,5,6,7,8,9} 
  wg.Add(1)

  go addStuff(mynums)
  wg.Wait()
  close(channel)
  recieveStuff(channel)
 }

 func addStuff(mynums []int) {

   for _, val := range mynums {
       channel <- val
   }
   wg.Done()
 }

 func recieveStuff(channel chan int) {
    for val := range channel{
    fmt.Println(val)
 }
} 

我遇到了死锁错误。我试图等待路由返回wg.Wait()?然后,关闭频道。然后,将通道发送到recievestuff方法以输出切片中的值?但它不起作用。我已经尝试在循环之后在go例程中移动close()方法,因为我认为我可能试图关闭main()中的错误例程。香港专业教育学院发现这个东西到目前为止来自java和c#相对混乱。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

wg.Wait()被调用一次之前,对wg.Done()的调用不会返回。

addStuff()中,当没有其他goroutine消耗这些值时,您正在为通道写入值。由于通道是无缓冲的,因此对channel <- val的第一次调用将永远阻塞,从而导致死锁。

此外,addStuff()中的通道仍为零,因为您在main中创建了一个新的变量绑定,而不是分配给包级变量。写入nil频道将永久阻止:

channel := make(chan int) //doesn't affect the package-level variable

这是一个修改后的示例,它通过使用通道中的所有值来运行完成:

https://play.golang.org/p/6gcyDWxov7