猿问

去选择语句

一个关于select频道声明的简短节目。


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 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)

}

上面代码的结果:


0

1

1

2

3

5

8

13

21

34

quit = 9

它工作得很好。但在我改变后(在func fibonacci)


case s := <-quit:

    fmt.Println("quit =",s)


case <-quit:

    fmt.Println(<-quit)

发生了致命错误:


0

1

1

2

3

5

8

13

21

34

fatal error: all goroutines are asleep - deadlock!


goroutine 1 [chan receive]:

main.fibonacci(0x18348040, 0x18348080)

    /tmp/compile42.go:12 +0xf9

main.main()

    /tmp/compile42.go:27 +0x11c

错误从何而来?


手掌心
浏览 196回答 2
2回答

HUH函数

在第二种情况下,您将两次从通道中获取值。每次执行类似 <-channel 之类的操作时,都会从 channel 中弹出一个值。因此程序无限期地在线等待fmt.Println(<-quit)但幸运的是,go 足够聪明,可以检测到这种情况,并因错误而恐慌“所有 goroutine 都睡着了——死锁!&nbsp;”

一只斗牛犬

线fmt.Println(<-quit)根据您拥有的代码,正在等待通道上的另一个值,该值永远不会出现。您必须记住选择之前的行:case&nbsp;s&nbsp;:=&nbsp;<-quit已经从频道中删除了退出值。因此它永远不会完成。
随时随地看视频慕课网APP

相关分类

Go
我要回答