user4211028
user4211028

Reputation:

Go WaitGroup with goroutine

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!

Upvotes: 8

Views: 2072

Answers (1)

VonC
VonC

Reputation: 1323753

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.

Upvotes: 1

Related Questions