golang协程执行顺序的问题

发布于 2022-09-13 00:53:53 字数 745 浏览 26 评论 0

最近面试遇到一个代码问题

package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    runtime.GOMAXPROCS(1)
    wg := sync.WaitGroup{}
    wg.Add(10)
    for i := 0; i < 5; i++ {
        go func() {
            fmt.Println("A:", i)
            wg.Done()
        }()
    }
    for i := 0; i < 5; i++ {
        go func(num int) {
            fmt.Println("B:", num)
            wg.Done()
        }(i)
    }
    wg.Wait()
}

问上面代码输出结果是啥?
我当时回答是

A: 5
A: 5
A: 5
A: 5
A: 5
B: 0
B: 1
B: 2
B: 3
B: 4

但是我跑代码后结果却是:

B: 4
A: 5
A: 5
A: 5
A: 5
A: 5
B: 0
B: 1
B: 2
B: 3

请教B: 4为啥会第一个打印,go的携程是如何调度的呢?我一开始还以为是用队列(先进先出的规则)来调度的呢,但并不是。

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

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

发布评论

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

评论(1

七月上 2022-09-20 00:53:53

本来以为是老套的 GMP 面试题,没啥意思,但仔细看了下感觉又不对。于是在爆栈搜了一圈之后找到个类似的问题,是问为什么连续启动多个goroutine总是先运行最后一个,例程和你的例子很像。

stackoverflow/goroutines-always-execute-last-in-first-out

能得到的一个首要的结论是:不要依赖于 goroutine 的调度顺序,在语言上这是未定义的(go 1.5 release note)。

In Go 1.5, the order in which goroutines are scheduled has been changed. The properties of the scheduler were never defined by the language, but programs that depend on the scheduling order may be broken by this change. We have seen a few (erroneous) programs affected by this change. If you have programs that implicitly depend on the scheduling order, you will need to update them.

就跟写 C/C++ 的时候依赖于某个编译器在某个平台上对某个未定义行为的行为一样,是非常不好的埋地雷行为,即使凑巧运行起来了,也应该直接视作 BUG。

遗憾的是依然没找到表现出这一行为的具体原因,只能确定这事儿不归我们这些只是 Go 写代码的搬砖工管。

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