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

标签 go channel

有些情况下您需要关闭 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)

最佳答案

第一个例子,由于使用了range, channel 需要关闭。关键词。当范围与 channel 一起使用时,它将继续尝试从 channel 读取数据,直到 channel 关闭。

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

[When using range for] ...channels, the iteration values produced are the successive values sent on the channel until the channel is closed. If the channel is nil, the range expression blocks forever.

这意味着您必须关闭 channel 以退出循环。

在第二个示例中,您使用的是接收运算符 <- .该运算符将阻塞,直到一个 项可以从 channel 中拉出。由于 channel 中有一件商品在等待配送,因此它会立即让出。在这种情况下,关闭是可选的,因为在那之后 channel 上没有其他阻塞操作,所以很高兴保持“打开”状态。

参见 channels section更多详情...

关于go - 我怎么知道关闭是必要的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19746629/

相关文章:

math - 为什么 math.Pow10(e int) 返回 float64 而不是 int64?

go - 另一个文件中的调用函数

http - r.PostForm 和 r.Form 总是空的

binary - 从 stdin 接收二进制数据,发送到 Go 中的 channel

go - 为什么这些 goroutines 的 WaitGroups 不能正常工作?

recursion - Go 中的组合和

map - 在 Go 中使用范围获取值不是线程安全的吗?

go - 将事物的 channel 作为 Go 中的接口(interface) channel 传递

go - Race 暂停一组 goroutines

csv - 为一个 channel 使用多个接收器