一尘不染

为什么这段关于golang goruntine运行顺序的代码首先是“ 2”

go

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是第一个推送队列。它应该首先打印。


阅读 244

收藏
2020-07-02

共1个答案

一尘不染

您不会将两个已启动的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上尝试一下。

2020-07-02