为了账号安全,请及时绑定邮箱和手机立即绑定

Goroutine阻止程序结束

Goroutine阻止程序结束

Go
宝慕林4294392 2022-08-01 17:11:19
我正在经历Go Tour,这段代码真的融化了我的思想:package mainimport "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都处于睡眠状态,所以我假设开放通道阻止程序返回和退出。问题是,为什么这会导致错误?程序结束了,通道有读取器,并且没有更多的代码语句要执行,那么这里到底发生了什么呢?cP.S 如果通道从未评估为 True,这是否意味着第一个情况将永远循环?quit
查看完整描述

1 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

tl;博士

由于您从未向频道写入任何内容,因此您的程序会在选择案例语句上死锁,您的程序会不断生成值并将其添加到没有使用者的频道中。quitc


解释

代码正在等待将某些内容添加到通道中。由于它没有被写入,程序继续计算斐波那契数列。quit


并发编程与“标准”线性规划非常不同。


您删除的行将保证通道中有足够的数据来结束节目,因为该函数仅在从中读取该通道时结束。quitfib


for { // an infinite loop

  case c <- x:

      x, y = y, x+y

  case <-quit:

      fmt.Println("quit")

      return // your only exit is here, 

             // which is only executed when data is read from the quit channel

}

您永远在计算值,您唯一的退出是写入通道;但是,这永远不会发生。quit


查看完整回答
反对 回复 2022-08-01
  • 1 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号