猿问

Goroutine阻止程序结束

我正在经历Go Tour,这段代码真的融化了我的思想:


package main


import "fmt"


func fibonacci(c, quit chan int) {

    x, y := 0, 1

    for {

        select {

        case c <- x:

            x, y = y, x+y

        case <-quit:

            fmt.Println("quit")

            return

        }

    }

}


func main() {

    c := make(chan int)

    quit := make(chan int)

    go func() {

        for i := 0; i < 5; i++ {

            fmt.Println(<-c)

        }

        // quit <- 0 // Suppose I remove this line (note that it is present in the Tour)

    }()

    fibonacci(c, quit)

}

现在我得到一个致命的错误,告诉我所有的goroutine都处于睡眠状态,所以我假设开放通道阻止程序返回和退出。


问题是,为什么这会导致错误?程序结束了,通道有读取器,并且没有更多的代码语句要执行,那么这里到底发生了什么呢?c


P.S 如果通道从未评估为 True,这是否意味着第一个情况将永远循环?quit


宝慕林4294392
浏览 146回答 1
1回答

慕哥6287543

tl;博士由于您从未向频道写入任何内容,因此您的程序会在选择案例语句上死锁,您的程序会不断生成值并将其添加到没有使用者的频道中。quitc解释代码正在等待将某些内容添加到通道中。由于它没有被写入,程序继续计算斐波那契数列。quit并发编程与“标准”线性规划非常不同。您删除的行将保证通道中有足够的数据来结束节目,因为该函数仅在从中读取该通道时结束。quitfibfor { // an infinite loop&nbsp; case c <- x:&nbsp; &nbsp; &nbsp; x, y = y, x+y&nbsp; case <-quit:&nbsp; &nbsp; &nbsp; fmt.Println("quit")&nbsp; &nbsp; &nbsp; return // your only exit is here,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// which is only executed when data is read from the quit channel}您永远在计算值,您唯一的退出是写入通道;但是,这永远不会发生。quit
随时随地看视频慕课网APP

相关分类

Go
我要回答