Golang“选择”似乎不公平



我是 Golang 的初学者,我从 select 的官方规范中读到,当更多的通信可以进行时,我会做统一的伪随机,但是当我尝试以下代码时

package main
import (
    "fmt"
)
func main() {
    // For our example we'll select across two channels.
    c1 := make(chan string)
    c2 := make(chan string)
    go func() {
        for {
            c1 <- "one"
        }
    }()
    go func() {
        for {
            c2 <- "two"
        }
    }()
    for i := 0; i < 100; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}

它总是打印"收到两个",似乎不是随机结果,所以我错在哪里?

代码可以在这里测试。

问题是你在Go Playground上运行它,在Go Playground上,GOMAXPROCS是1,这意味着一次执行一个goroutine,如果该goroutine没有阻塞,调度程序不会被迫切换到其他goroutines。

因此,您应该在本地计算机中运行它,以查看实际结果

当您在本地运行时,很可能 GOMAXPROCS 将大于 1 因为它默认为可用的 CPU 内核数量(自 Go 1.5 以来(。所以 如果你有一个goroutine执行无限循环并不重要, 另一个 goroutine 将同时执行,它将是 main((,当 main(( 返回时,你的程序终止;它没有 等待其他非主 goroutines 完成

根据所使用的 Go 版本,它可能是; 请参阅此问题。它应该在 Go 1.10 中修复(关于这个,它在 Go 1.9.2 中修复,但我还没有测试过(。

最新更新