我怎么知道关闭是必要的?

时间:2013-11-02 20:40:15

标签: go channel

在某些情况下,您需要关闭频道,有些情况则需要关闭频道。

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)

1 个答案:

答案 0 :(得分:5)

由于range关键字的使用,需要关闭频道的第一个示例。当范围与通道一起使用时,它将继续尝试从通道读取,直到通道关闭。

来自http://golang.org/ref/spec#For_statements

  

[当使用range] ...通道时,产生的迭代值是通道上发送的连续值,直到通道关闭。如果通道为nil,则范围表达式将永久阻塞。

这意味着 关闭频道以退出循环。

在第二个示例中,您正在使用接收运算符<-。此运算符将阻塞,直到一个项目被拉出通道。由于在通道中有一个等待交付的物品,它将立即产生。在这种情况下,close是可选,因为此后通道上没有其他阻塞操作,因此保持“开放”状态也很高兴。

有关详细信息,请参阅channels section