【问题标题】:Go Tour #5: select statement exampleGo Tour #5:选择语句示例
【发布时间】:2020-07-10 04:57:38
【问题描述】:

我是 Go 语言的新手,目前正在参加 Go 之旅。我对select 声明中的concurrency example 5 有疑问。

下面的代码已经用打印语句进行了编辑,以跟踪语句的执行。

package main

import "fmt"

func fibonacci(c, quit chan int) {
    x, y := 0, 1
    fmt.Printf("Run fib with c: %v, quit: %v\n", c, quit)
    for {
        select {
        case c <- x:
            fmt.Println("Run case: c<-x")
            x, y = y, x+y
            fmt.Printf("x: %v, y: %v\n", x, y)
        case <-quit:
            fmt.Println("Run case: quit")
            fmt.Println("quit")
            return
        }
    }
}

func runForLoop(c, quit chan int) {
    fmt.Println("Run runForLoop()")
    
    for i := 0; i < 10; i++ {
        fmt.Printf("For loop with i: %v\n", i)
        fmt.Printf("Returned from c: %v\n", <-c)
    }
    
    quit <- 0
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go runForLoop(c, quit)
    fibonacci(c, quit)
}

以下内容打印到控制台。

Run fib with c: 0xc00005e060, quit: 0xc00005e0c0
Run runForLoop()
For loop with i: 0
Returned from c: 0 // question 1
For loop with i: 1
Run case: c<-x // question 2
x: 1, y: 1
Run case: c<-x // question 2
x: 1, y: 2
Returned from c: 1
For loop with i: 2
Returned from c: 1
For loop with i: 3
// ...

我的问题是

    1. 这里收到的c 的值是0,即使没有执行任何选择块。我能否确认这是具有 int 类型的 c 变量的零值?
    1. 为什么 case c&lt;-x 被执行了两次?

【问题讨论】:

    标签: go concurrency


    【解决方案1】:

    对于 1:它打印&lt;-c 的结果,这将阻塞直到另一个 goroutine 写入它。所以你的陈述不正确:c&lt;-x 的选择案例与x=0 一起运行。它不是 chan 变量的零值。如果通道关闭,或者如果您使用通道读取的二值形式:value,ok := &lt;-c,您只会从通道中读取 chan 类型的零值。当ok=false时,value为通道值类型的零值。

    对于 2:c&lt;-x 将执行 10 次,因为您在 for 循环中读取了 10 次,然后才写入quit,这将启用选择的第二种情况。您在此处观察到的是循环的第二次迭代。

    【讨论】:

    • 嗨,布拉克,感谢您的回复。对于 1:如果 c
    • For 2:我知道 c
    • @quattad - 对于 1:如果 c
    • @quattad for 1:两个 goroutine 之间没有执行顺序保证。另一个 goroutine 可以随时抢占正在运行的 goroutine,在这种情况下,它在打印输出之前就抢占了
    • @quattad #2 也是同样的原因。当一个 goroutine 写入一个通道时,另一个 goroutine 读取它,此时两个 goroutine 都被启用。它们可以按任何顺序执行。
    猜你喜欢
    • 2018-10-06
    • 2012-11-10
    • 2023-04-11
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多