select - 为什么golang select语句不随机选择一个case

标签 select go goroutine

这类似于 go tutorial select statement ,但我没有从那个帖子得到答案。所以我在这里问。感谢您的回答。

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

基于句子“A select blocks until its cases can run, then it execute that case. It chooses an random if multiple are ready.”,当“case <-quit:”也准备好了时, select 语句应从“case c <- x:”和“case <-quit:”中随机选择。但是程序总是进入“case <-quit:” case。

我还将选择 block 更改为如下所示。然后在前 10 次循环中,程序随机打印 1-6,但程序退出一次(第 11 次输出)退出 channel 的值为 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

关于select - 为什么golang select语句不随机选择一个case,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36335779/

相关文章:

MVC 4 Controller 中的 SQL 选择

Go SSH key 不能与 crypto/ssh 一起使用,但可以手动使用

go - 在 Go 中取消阻塞操作

Go xml.Unmarshal 仅获取列表的最后一项

go - 为什么在我的代码中 goroutine 似乎自动卡住循环变量

go - Goroutines节气门示例

mysql - SQL通过许多相关的外键进行选择

jquery - 参数列表后缺少 ) ? jQuery

mysql - 选择查询具有父子关系的类别数据

使用 preg_match 去路由