为什么golang select语句不会随机选择一个案例

时间:2016-03-31 14:07:26

标签: select go goroutine

这类似于go tutorial select statement,但我没有从该帖子中得到答案。所以我在这里问。谢谢你回答。

http://tour.golang.org/concurrency/5中,似乎"案例c< - x:"总是准备好,这意味着这种情况不会阻止select语句。

基于句子" A选择块直到其中一个案例可以运行,然后执行该案例。如果多个准备就绪,它会随机选择一个。",当" case< -quit:"也准备好了,select语句应该随机选择" case c< - x:" &" case< -quit:"。但该程序总是进入" case< -quit:"情况下。

我还将选择块更改为如下所示。然后在前10个循环中,程序随机打印1-6,但程序退出一次(第11个输出)退出通道的值为0.

我的问题是,如果从中随机选择就绪案例,那么为什么第11次选择总是退出案例。

select {
    case c <- 1:
        x, y = y, x+y
    case c <- 2:
        x, y = y, x+y
    case c <- 3:
        x, y = y, x+y
    case c <- 4:
        x, y = y, x+y
    case c <- 5:
        x, y = y, x+y
    case c <- 6:
        x, y = y, x+y
    case <-quit:
        fmt.Println("quit")
        return
    }

1 个答案:

答案 0 :(得分:4)

在案例陈述中,您要将值发送到c(例如c <- 1),这些值会阻止,直到某些内容读取为foo := <- c。当某些内容写入quit时,它会触及<-quit所处的情况并返回选择范围。

从这个例子中

package main

import (
    "fmt"
    "time"
)

func main() {
    c := make(chan int)
    quit := make(chan struct{})

    go func(q chan<- struct{}) {
        time.Sleep(5 * time.Second)
        q <- struct{}{}
    }(quit)

    go func(ch chan<- int) {
        var x int
        for range time.Tick(1 * time.Second) {
            c <- x
            x++
        }
    }(c)

    for {
        select {
        case foo := <-c:
            fmt.Println("Foo", foo)
        case bar := <-c:
            fmt.Println("Bar", bar)
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

您可以在计算机上看到随机打印的值:

$ go run foo.go
Bar 0
Bar 1
Foo 2
Bar 3
quit

$ go run foo.go
Bar 0
Foo 1
Bar 2
Bar 3
quit