关闭Go

时间:2016-04-17 12:59:47

标签: go channel

我正在学习通道如何在Go中工作并且偶然发现了关闭频道的问题。这是来自 A Tour of Go 的修改示例,它生成n-1个斐波纳契数并通过通道发送它们,留下最后一个"元素"未使用的信道容量。

func fibonacci(n int, c chan int) {
    x, y := 0, 1
    for i := 0; i < n-1; i++ {
        c <- x
        x, y = y, x+y

    }
    // close(c) // It's commented out on purpose
}

func main() {
    n := 10
    c := make(chan int, n)
    go fibonacci(n, c)

    for i := 0; i < n; i++ {
        _, ok := <-c
        fmt.Println(ok)
    }
}

问题是我得到了:

  

致命错误:所有goroutine都睡着了 - 死锁!

当我不关闭频道时。究竟是什么导致了僵局?当我不关闭它时,为什么我无法从通道的容量边界收到它?

2 个答案:

答案 0 :(得分:5)

您正在将 n 值写入通道(从0到 n-1 ),但正在尝试读取 n + 1 通道中的值(从0到 n )。如果没有明确关闭通道,main函数将永远等待最后一个值。

  

究竟是什么导致了僵局?

n 迭代之后,运行fibonacci函数的goroutine将退出。在此goroutine退出之后,程序中唯一剩下的goroutine是main goroutine,而这个goroutine正在等待将一些数据写入c通道 - 并且因为没有其他goroutine离开那可能会将数据写入此频道,它将永远等待。这正是错误消息试图告诉您的内容:“所有goroutines (”all“只是”one“,这里)睡着了”

_, ok := <- c函数中的main调用只会在c频道关闭时停止阻止(因为从频道读取阻止,这需要从另一个频道完成够程)。当通道关闭时,main功能将从通道读取剩余数据(当它是缓冲通道时)

答案 1 :(得分:0)

对于主要期望在通道中进行n次通信的循环,但是在func fibonacci中只产生n-1

func fibonacci(n int, c chan int) {
    x, y := 0, 1
    for i := 0; i < n; i++ { //here
        c <- x
        x, y = y, x+y

    }
    // close(c) // It's commented out on purpose
}

应该有效 http://play.golang.org/p/zdRuy14f9x