Go WaitGroup with goroutine
Asked Answered
S

1

8

I wonder why we need to run the wg.Wait() in goroutine

// This one works as expected...
func main() {
    var wg sync.WaitGroup
    for i:=0; i<5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
        }()
        time.Sleep(time.Second)
    }
    go func() {
        wg.Wait()
    }()
}

But this one never ends waiting forever

func main() {
    var wg sync.WaitGroup
    for i:=0; i<5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
        }()
        time.Sleep(time.Second)
    }
    wg.Wait()
}

Can anybody explain why I need to wait in another goroutine?

Thanks!

Stabler answered 4/12, 2014 at 7:24 Comment(3)
Are you sure? I'd guess something is broken in the not shown part of the code, especially as the first version doesn't wait IMHO.Raindrop
My code actually does a lot more, which uses its own goroutines again. I get this pattern from github.com/rakyll/coop/blob/master/coop.go#L85Stabler
Here, she does wg.Wait() in goroutine.Stabler
B
1

why we need to run the wg.Wait() in goroutine?

In the example you mention (coop/blob/master/coop.go#L85), the wait is in a goroutine in order to return immediately a channel that will indicate when all the other goroutines have completed. Those are the goroutines to be started:

for _, fn := range fns {
    go func(f func()) {
        f()
        wg.Done()
    }(fn)
}

They mention the completion through the var wg sync.WaitGroup.
That WaitGroup is set to wait for the right number of goroutines to finish:

wg.Add(len(fns))

The wait is done in a goroutine because it will in turn signal the global completion to a channel:

go func() {
    wg.Wait()
    doneSig(ch, true)
}()

But the channel is returned immediately.

ch := make(chan bool, 1)
...
return ch

That is why the Wait is done asynchronously: you don't want to wait in this function. You just want the channel.

Bieber answered 4/12, 2014 at 8:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.