去旅游#5 : select statement example

标签 go concurrency

我是 Go 语言的新手,目前正在参加 Go 之旅。我有一个关于 concurrency example 5 的问题在 select陈述。
下面的代码已使用打印语句进行编辑,以跟踪语句的执行。

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
// ...
我的问题是

  • c 的值这里收到的是0即使没有执行任何选择 block 。我可以确认这是 c 的零值吗?具有 int 的变量类型?


  • 为什么是案例c<-x执行两次?

  • 最佳答案

    对于 1:它打印 <-c 的结果, 这将阻塞直到另一个 goroutine 写入它。所以你的陈述不正确:c<-x 的选择案例运行,与 x=0 .它不是 chan 变量的零值。如果 channel 关闭,或者如果您使用 channel 读取的二值形式,您只会从 channel 中读取 chan 类型的零值:value,ok := <-c .当ok=false , value是 channel 值类型的零值。
    对于 2:c<-x将执行 10 次,因为您在 for 循环中读取了 10 次,然后才写入 quit ,这将启用选择的第二种情况。您在这里观察到的是循环的第二次迭代。

    关于去旅游#5 : select statement example,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62827577/

    相关文章:

    go - 我们如何确定 "last"工作进程/线程在 Go 中何时完成?

    multithreading - 关于多线程、并发和并行

    google-app-engine - 将字符串数据转换为在 Go AppEngine 上读取的结构 : Inserted on Java AppEngine (Objectify),

    go - 使用 apimachinery/client-go 检索不包含标签的 kubernetes 节点

    去正确的行为,或编译器错误?

    go - 使用值或指针接收器实现 Stringer 接口(interface)

    go - 如何正确实现并发 goroutines(和/或限制它们)以产生一致的结果?

    sql - 使用 Entity Framework == EntityException 并发访问数据库

    Java 内存模型操作

    go - 哪个更适合测试非有限 float IsNaN 或 IsInf?