首页 > 解决方案 > 为什么这个关于golang goruntine运行顺序的代码是“2”第一

问题描述

package main

import (
    "fmt"
    "sync"
)

func main() {
    runtime.GOMAXPROCS(1)
    w := &sync.WaitGroup{}
    w.Add(2)
    go func() {
        fmt.Println("1")
        w.Done()
    }()
    go func() {
        fmt.Println("2")
        w.Done()
    }()
    w.Wait()
}

https://play.golang.org/p/ESi1mKAo1x_S

嗯,我不知道为什么“2”是先打印的。

我想检查信息。但我不知道应该检查什么信息。所以我在那里发布问题以寻求帮助。

我认为第一个 goroutine 是第一个 push in queue。它应该先打印。

标签: gogoroutine

解决方案


您没有将 2 个启动的 goroutine相互同步,因此无法保证它们的运行顺序。您同步的唯一事情是等待其他 2 个完成的主 goroutine,但它们的顺序将是未定义的。

这是一个使用另一个同步订单的示例sync.WaitGroup

w := &sync.WaitGroup{}
w.Add(2)

w2 := &sync.WaitGroup{}
w2.Add(1)
go func() {
    fmt.Println("1")
    w.Done()
    w2.Done()
}()
go func() {
    w2.Wait()
    fmt.Println("2")
    w.Done()
}()
w.Wait()

输出将是(在Go Playground上尝试):

1
2

基本上,第二个 goroutine 等待w2,一旦完成,它就会在第一个 goroutine 中调用。

请注意,由于第二个 goroutine 等待第一个,因此主 goroutine 只等待第二个 goroutine 就足够了(这意味着等待两者)。所以上面的例子可以这样写:

w2 := &sync.WaitGroup{}
w2.Add(1)
go func() {
    fmt.Println("1")
    w2.Done()
}()

w := &sync.WaitGroup{}
w.Add(1)
go func() {
    w2.Wait()
    fmt.Println("2")
    w.Done()
}()
w.Wait()

输出是一样的。在Go Playground上试试这个。


推荐阅读