Something I missed previously when reading the Go 1.25 release note in the “minor changes to the library” section: an entry for the sync package:
sync
The new WaitGroup.Go method makes the common pattern of creating and counting Goroutines more convenient.
It’s a small improvement that makes it harder to make mistakes so this is more than just convenience! Let’s see how it looks.
Below I am assuming that you are already slightly familiar with Go concurrency and the sync package in the Go standard library. If not, you should start there first :)
sync.WaitGroup.Add() + defer sync.WaitGroup.Done()Before Go 1.25, the way to use sync.WaitGroup to count Goroutines was as follow:
|
|
The example is borrowed from Rob Reid’s blog post runtime.Goexit1 where he discusses a few alternatives way to implement this pattern, with the tools available in 2018.
One additional note: this code is assuming we don’t have access to the run function.
sync.WaitGroup.Go()Rewriting the previous example for Go v1.25 and newer versions. This is also now the preferred way to use sync.WaitGroup according to the docs for Add and Done
Callers should prefer [WaitGroup.Go]
|
|
The good things
sync.WaitGroup.Add(n) in the main Goroutine, this is automatically handled for you.defer sync.WaitGroup.Done() in each of the Goroutines, this is automatically handled for you.run function or not.The negative I think is that by not using the keyword go directly, but instead using a normal library function that wraps it, when quickly looking over the code (like diagonal reading), you might miss the Goroutine creation since we are so used to see the go keyword highlighted in our favorite IDE. Would that be enough to not use it though? I don’t think so!
A few more links to stay on the topic of Go concurrency