在某些情况下,您需要关闭频道,有些情况则需要关闭频道。
http://play.golang.org/p/piJHpZ2-aU
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)
for elem := range queue {
fmt.Println(elem)
}
我来这里
fatal error: all goroutines are asleep - deadlock!
而此代码的关闭是可选的
http://play.golang.org/p/Os4T_rq0_B
jobs := make(chan int, 5)
done := make(chan bool)
go func() {
for {
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")
<-done
// close(done)
答案 0 :(得分:5)
由于range
关键字的使用,需要关闭频道的第一个示例。当范围与通道一起使用时,它将继续尝试从通道读取,直到通道关闭。
来自http://golang.org/ref/spec#For_statements
[当使用
range
] ...通道时,产生的迭代值是通道上发送的连续值,直到通道关闭。如果通道为nil,则范围表达式将永久阻塞。
这意味着 关闭频道以退出循环。
在第二个示例中,您正在使用接收运算符<-
。此运算符将阻塞,直到一个项目被拉出通道。由于在通道中有一个等待交付的物品,它将立即产生。在这种情况下,close是可选,因为此后通道上没有其他阻塞操作,因此保持“开放”状态也很高兴。
有关详细信息,请参阅channels section