Channel vs WaitGroup

4,222 views
Skip to first unread message

Rohit

unread,
Jun 7, 2011, 4:52:07 AM6/7/11
to golang-nuts
Hello,

I have found two ways of signaling that a bunch of goroutines have
finished.

1. Pass all the child goroutines a channel, which they report success
on. The main routine receives all the messages on the channel and
discards them. Something like:

for i:=0; i < n; i++ {
go func() {
// do something
ch <- true
}
}

for i:=0; i < n; i++ {
<- ch
}


2. Or you pass all the goroutines a WaitGroup and make them report
back by calling the WaitGroup.Done method. The main goroutine waits
for everyone to finish:

var wg WaitGroup
wg.Add(n)
for i:=0; i < n; i++ {
go func() {
// do something
wg.Done()
ch <- true
}
}
wg.Wait()

Would I expect to see any difference in performance between the two
approaches? Which one should be preferred over the other?

Thanks,
Rohit

Rohit

unread,
Jun 7, 2011, 4:54:42 AM6/7/11
to golang-nuts
Correction, the second snippet should read:
var wg WaitGroup
wg.Add(n)
for i:=0; i < n; i++ {
go func() {
// do something
wg.Done()
}
}
wg.Wait()

The "ch <- true" statement shouldn't have been there after wg.Done().

Rohit

roger peppe

unread,
Jun 7, 2011, 5:03:30 AM6/7/11
to Rohit, golang-nuts
the channel approach is more general, allowing direct communication
between the terminating goroutine and the waiter, for example
to send result data.

the WaitGroup approach may be more efficient, and is also
easier to use if the number of goroutines is not known
in advance.

both can be appropriate at different times.

Jonathan Langevin

unread,
Dec 9, 2013, 2:02:57 PM12/9/13
to golan...@googlegroups.com
The manual shows the following as the example usage, notice the difference(s) from your example:

var wg sync.WaitGroup
    var urls = []string{
            "http://www.golang.org/",
            "http://www.google.com/",
            "http://www.somestupidname.com/",
    }
    for _, url := range urls {
            // Increment the WaitGroup counter.
            wg.Add(1)
            // Launch a goroutine to fetch the URL.
            go func(url string) {
                    // Decrement the counter when the goroutine completes.
                    defer wg.Done()
                    // Fetch the URL.
                    http.Get(url)
            }(url)
    }
    // Wait for all HTTP fetches to complete.
    wg.Wait()

Dmitry Vyukov

unread,
Dec 9, 2013, 2:07:16 PM12/9/13
to Rohit, golang-nuts
I would expect that WaitGroup is currently faster.
Reply all
Reply to author
Forward
0 new messages