liveBook · Manning

WaitGroup

As explained in Learn Go with Pocket-Sized Projects

sync.WaitGroup is a Go synchronization type that allows one goroutine to wait for a collection of goroutines to finish.

A sync.WaitGroup lets one goroutine wait for a collection of goroutines to finish. Register work with Add, launch goroutines, defer Done in each goroutine, and call Wait as the synchronization point. section 7.2.4

Coordinate concurrent cooking tasks

Create a pointer to a WaitGroup, call Add(2), launch the cooking functions, and wait for both to report completion. Pass the pointer rather than a copy; otherwise Done updates a different WaitGroup and Wait can panic. section 7.2.4

Listing 7.7 Cooking example using sync.WaitGroup
package main

import (
    "fmt"
    "sync"
)

func main() {
    wg := &sync.WaitGroup{} #1
    wg.Add(2) #2

    go cookRice(wg) #3
    go cookCurry(wg)  #3

    wg.Wait() #4
}

func cookRice(wg *sync.WaitGroup) {
    defer wg.Done() #5
    fmt.Println("Cooking rice...")
    // prepare rice
}

func cookCurry(wg *sync.WaitGroup) {
    defer wg.Done() #5
    fmt.Println("Preparing curry sauce...")
    // prepare curry
}

Runnable cooking example showing Add before goroutine launch, deferred Done, and Wait after starting both goroutines. section 7.2.4

Use the core operations in this order:

  • Call Add with the number of goroutines being tracked; call Add repeatedly when work is discovered in a loop. section 7.2.4
  • Defer Done at the start of every tracked goroutine so completion is reported even when the function returns early. section 7.2.4
  • Call Wait only after Add and goroutine launch, then continue when the corresponding Done calls have completed. section 7.2.4
  • Keep tracking near the coordinator that knows how many goroutines it started; defer Wait when a listener must not return early. section 9.5.1
  • Use errgroup.Group instead when goroutine errors need handling; use WaitGroup when errors require no specific treatment. section 7.6

Parallel cache test

A test can register ten tasks, start one goroutine per task, defer Done in each closure, and wait before the test returns. Running concurrent writes can expose cache races when combined with race testing. section 7.3.1 section 7.6

How Learn Go with Pocket-Sized Projects covers it

How deep it goes
Explains Add, Done, and Wait with runnable examples, pointer semantics, loop registration, and coordinator placement.
Examples
Uses cooking tasks, a ten-writer cache test, and a concurrent maze solver listener.
What it assumes
Assumes familiarity with goroutines and functions, while teaching synchronization, pointer passing, deferred cleanup, and loop-safe closures.
What you can do after
Build it from scratch to coordinate goroutines, wait for completion, and structure concurrent tests.
How it connects
Connects goroutines, channels, errgroup.Group, mutexes, data races, and loop-variable capture.

Also explained in

Compare how 5 books explain WaitGroup →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Go with Pocket-Sized Projects. The section links point to the parts of the book it draws on.