go语言里面关于channel和select的问题

发布于 2022-09-06 15:52:28 字数 1476 浏览 14 评论 0

我有段代码是启动了一个goroutine,在一个无限循环中给一个channel数组中一个随机元素赋值,主线程使用select从中取值,但是通过打印我发现,goroutine执行两次循环后,切换到主线程,,特别有规律,这是为什么?这种切换不是cpu随机的吗?怎么会有这种规律性?(可以看x和y的打印结果)
代码如下:
package main

import (

"math/rand"
"fmt"
"time"

)

func main() {

rand.Seed(time.Now().UTC().UnixNano())
channels := make([]chan bool, 6)
for i := range channels {
    channels[i] = make(chan bool)
}
go func() {
    for {
        y := rand.Intn(6)

        fmt.Printf("y:%d\n", y)
        channels[y] <- true

    }
}()
for i := 0; i < 36; i++ {
    var x int
    select {
    case <-channels[0]:
        x = 1
    case <-channels[1]:
        x = 2
    case <-channels[2]:
        x = 3
    case <-channels[3]:
        x = 4
    case <-channels[4]:
        x = 5
    case <-channels[5]:
        x = 6
    }
    fmt.Printf("x:%d\n", x)
}
fmt.Println()

}
输出结果:
y:2
y:2
x:3
x:3
y:1
y:2
x:2
x:3
y:0
y:2
x:1
x:3
y:1
y:2
x:2
x:3
y:1
y:5
x:2
x:6
y:0
y:1
x:1
x:2
y:4
y:5
x:5
x:6
y:1
y:4
x:2
x:5
y:0
y:5
x:1
x:6
y:5
y:1
x:6
x:2
y:2
y:0
x:3
x:1
y:3
y:3
x:4
x:4
y:1
y:2
x:2
x:3
y:1
y:3
x:2
x:4
y:5
y:2
x:6
x:3
y:4
y:0
x:5
x:1
y:2
y:1
x:3
x:2
y:4
y:1
x:5
x:2

Process finished with exit code 0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

停滞 2022-09-13 15:52:28

cpu 和 goroutine 默认情况下并不是 1:1 的关系,对各个 goroutine 的调度是 go runtime 的调度器决定的

沩ん囻菔务 2022-09-13 15:52:28

因为你用的阻塞模式, 两个协程形成互相依赖.

发送方 channels[y] <- true 被阻塞, 直到接收方 case <-channels[x]: 接收了, 反向亦然.

你可以设置 channel 缓存观察不一样的结果, 示例如下

package main
import (
    "fmt"
    "math/rand"
    "time"
)
func main() {
    rand.Seed(time.Now().UTC().UnixNano())
    channels := make([]chan bool, 6)
    for i := range channels {
        channels[i] = make(chan bool, 6)
    }
    go func() {
        for i := 0; i < 36; i++ {
            y := rand.Intn(6)
            fmt.Printf("y:%d\n", y)
            channels[y] <- true
        }
    }()
    for i := 0; i < 36; i++ {
        var x int
        select {
        case <-channels[0]:
            x = 1
        case <-channels[1]:
            x = 2
        case <-channels[2]:
            x = 3
        case <-channels[3]:
            x = 4
        case <-channels[4]:
            x = 5
        case <-channels[5]:
            x = 6
        }
        fmt.Printf("x:%d\n", x)
    }
    fmt.Println()
}
帅气尐潴 2022-09-13 15:52:28

这种情况可能是两个goroutine并行执行

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文