Skip to main content

Command Palette

Search for a command to run...

Golang Concurrency #7 - WaitGroup

Updated
2 min read
Golang Concurrency #7 - WaitGroup
T

Just a guy who loves to write code and watch anime.

Introduction

WaitGroups solve the problem: "How do I wait for multiple goroutines to finish?"

The Problem

func main() {
    go doWork("Job 1")
    go doWork("Job 2")
    go doWork("Job 3")

    fmt.Println("All done!")  // Prints immediately, jobs still running
}

Main function exits before goroutines finish. You need to wait for them.

Bad Solution

func main() {
    go doWork("Job 1")
    go doWork("Job 2")
    go doWork("Job 3")

    time.Sleep(5 * time.Second)  // Guess how long to wait
    fmt.Println("All done!")
}

What if jobs take 6 seconds? What if they take 1 second? You're either waiting too long or not long enough.

Good Solution -> WaitGroup

func main() {
    var wg sync.WaitGroup

    wg.Add(3)  // "I'm expecting 3 goroutines to finish"

    go doWork("Job 1", &wg)
    go doWork("Job 2", &wg)
    go doWork("Job 3", &wg)

    wg.Wait()  // Block until all 3 call Done()
    fmt.Println("All done!")
}

func doWork(name string, wg *sync.WaitGroup) {
    defer wg.Done()  // "I'm finished" (decrements counter)

    fmt.Printf("Starting %s\n", name)
    time.Sleep(2 * time.Second)  // Simulate work
    fmt.Printf("Finished %s\n", name)
}

How WaitGroup works

  1. Add(3) sets internal counter to 3

  2. Each Done() decrements the counter (3→2→1→0)

  3. Wait() blocks until counter reaches 0

Common pattern

var wg sync.WaitGroup

for i := 0; i < 10; i++ {
    wg.Add(1)
    go func(jobID int) {
        defer wg.Done()
        processJob(jobID)
    }(i)
}

wg.Wait()  // Wait for all 10 jobs

Important rules

  • Always call Add() before starting goroutines

  • Always call Done() exactly once per goroutine

  • Use defer wg.Done() to ensure it runs even if goroutine panics

WaitGroups are like taking attendance -> you know how many people you're expecting, and you wait until everyone checks in.