Golang`select`似乎不公平

时间:2018-01-16 03:29:17

标签: go concurrency

我是Golang的初学者,我从官方spec of 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)
        }
    }
}

它始终打印并收到两个&#39;,似乎不是随机结果,所以我错在哪里?

代码可以是测试here

2 个答案:

答案 0 :(得分:5)

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

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

  

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

答案 1 :(得分:0)

根据使用的Go版本,它可能是;见this issue。它应该在Go 1.10中修复(关于this one,它在Go 1.9.2中修复但我没有测试过。)