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

去选择语句

去选择语句

Go
手掌心 2021-10-25 20:24:42
一个关于select频道声明的简短节目。package mainimport "fmt"func fibonacci(c, quit chan int) {    x, y := 0, 1    for {        select {        case c <- x:            x, y = y, x+y        case s := <-quit:            fmt.Println("quit =",s)            return        }    }}func main() {    c := make(chan int)    quit := make(chan int)    go func() {        for i := 0; i < 10; i++ {            fmt.Println(<-c)        }        quit <- 9    }()    fibonacci(c, quit)}上面代码的结果:0112358132134quit = 9它工作得很好。但在我改变后(在func fibonacci)case s := <-quit:    fmt.Println("quit =",s)到case <-quit:    fmt.Println(<-quit)发生了致命错误:0112358132134fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan receive]:main.fibonacci(0x18348040, 0x18348080)    /tmp/compile42.go:12 +0xf9main.main()    /tmp/compile42.go:27 +0x11c错误从何而来?
查看完整描述

2 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

在第二种情况下,您将两次从通道中获取值。每次执行类似 <-channel 之类的操作时,都会从 channel 中弹出一个值。

因此程序无限期地在线等待

fmt.Println(<-quit)

但幸运的是,go 足够聪明,可以检测到这种情况,并因错误而恐慌“所有 goroutine 都睡着了——死锁! ”


查看完整回答
反对 回复 2021-10-25
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

线

fmt.Println(<-quit)

根据您拥有的代码,正在等待通道上的另一个值,该值永远不会出现。

您必须记住选择之前的行:

case s := <-quit

已经从频道中删除了退出值。

因此它永远不会完成。


查看完整回答
反对 回复 2021-10-25
  • 2 回答
  • 0 关注
  • 195 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信