Golang `select` 似乎不公平

标签 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)
        }
    }
}

它总是打印'received two',似乎不是随机结果,所以我哪里错了?

代码可以测试here .

最佳答案

问题是你在 go playground 上运行它,在 Go playground 上,GOMAXPROCS为1,,表示一次执行一个goroutine,如果那个goroutine不阻塞,调度器不会强制切换到其他goroutine。

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

When you run it locally, most likely GOMAXPROCS will be greater than 1 as it defaults to the number of CPU cores available (since Go 1.5). So it doesn't matter if you have a goroutine executing an endless loop, another goroutine will be executed simultaneously, which will be the main(), and when main() returns, your program terminates; it does not wait for other non-main goroutines to complete

关于Golang `select` 似乎不公平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48273670/

相关文章:

sql-server - 使用GORM在同一张表上设置两个外键时,MS-SQL服务器引发错误

go - 在不指定类型的情况下在 Go 中声明变量

go - 如何使用索引构造翻转的单个位位域?

go - `.text' 节中的 cgo 错误无法识别的重定位 (0x2a)

database - 如何使用 actor 进行数据库访问和 DDD?

qt - QML:WorkerScript 的线程模型

go - 如何确保自定义数据结构的编译时安全

java - 将对象重新放入 ConcurrentHashMap 是否会导致 "happens-before"内存关系?

c# - ParallelExtensions "Extras"是否仍然有值(value)?

python - 如何配置 celery 从队列中同时执行任务