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



类似于go教程选择语句,但我没有从那篇帖子中得到答案。所以我在这里问。感谢您的回答。

在 http://tour.golang.org/concurrency/5 中,似乎"case c <- x:"始终准备就绪,这意味着这种情况不会阻止 select 语句。

基于句子"A select 阻止,直到其其中一个案例可以运行,然后执行该案例。如果多个准备就绪,它会随机选择一个",当"case <-quit:"也准备就绪时,select 语句应从"case c <- x:"和"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
    }

在 case 语句中,您将值发送到 c(例如 c <- 1 (,这会阻塞,直到某些内容从 c 读取为 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

最新更新