why this code about golang goruntine running order is "2" first

Issue

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

eh,I don’t know why the “2” is print first.

I want to check the information.But I don’t know what’s information should I check.So I post the question there for help.

I think the first goroutine is the first one push in queue怂The it should be print first.

Solution

You’re not synchronizing your 2 launched goroutines to each other, so there is no guarantee in what order they run. The only thing you synchronize is the main goroutine to wait for the other 2 to complete, but their order will be undefined.

Here’s an example that also synchronizes order using another 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()

Output will be (try it on the Go Playground):

1
2

Basically the 2nd goroutine waits for w2, which is called in the 1st goroutine once it’s done.

Note that since the 2nd goroutine waits for the first, it is enough for the main goroutine to only wait for the 2nd goroutine (which transitively means to wait for both). So the above example can be written like this:

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()

Output is the same. Try this one on the Go Playground.

Answered By – icza

Answer Checked By – Katrina (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.