0
0
GoHow-ToBeginner · 3 min read

How to Wait for Goroutine to Finish in Go: Simple Guide

In Go, you can wait for a goroutine to finish by using a sync.WaitGroup. Add the number of goroutines to the WaitGroup, call Done() inside each goroutine when it finishes, and use Wait() to block until all are done.
📐

Syntax

The sync.WaitGroup type helps you wait for multiple goroutines to finish. You use three main methods:

  • Add(n int): Set how many goroutines to wait for.
  • Done(): Call this inside each goroutine when it finishes.
  • Wait(): Blocks the main goroutine until all added goroutines call Done().
go
var wg sync.WaitGroup
wg.Add(1) // Tell WaitGroup to wait for 1 goroutine

// Inside goroutine:
wg.Done() // Signal that goroutine is done

wg.Wait() // Wait here until all goroutines finish
💻

Example

This example shows how to start a goroutine, wait for it to finish, and then print a message.

go
package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var wg sync.WaitGroup

	wg.Add(1) // We will wait for 1 goroutine

	go func() {
		defer wg.Done() // Mark this goroutine as done when it finishes
		time.Sleep(2 * time.Second) // Simulate work
		fmt.Println("Goroutine finished")
	}()

	wg.Wait() // Wait for the goroutine to finish
	fmt.Println("Main function ends")
}
Output
Goroutine finished Main function ends
⚠️

Common Pitfalls

One common mistake is forgetting to call wg.Done() inside the goroutine, which causes Wait() to block forever. Another is calling Wait() before starting goroutines or before Add(), which can cause race conditions or panic.

Always call Add() before starting goroutines and Done() exactly once per goroutine.

go
package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var wg sync.WaitGroup

	wg.Add(1)

	go func() {
		// Forgot wg.Done() here - this will cause wg.Wait() to block forever
		time.Sleep(1 * time.Second)
		fmt.Println("Goroutine finished but did not call Done")
	}()

	// This will block forever because Done() was never called
	// wg.Wait()

	// Correct way:
	// go func() {
	// 	defer wg.Done()
	// 	time.Sleep(1 * time.Second)
	// 	fmt.Println("Goroutine finished")
	// }()
	// wg.Wait()
}
📊

Quick Reference

Remember these key points when waiting for goroutines:

  • Use sync.WaitGroup to wait for multiple goroutines.
  • Call Add(n) before starting goroutines.
  • Call Done() once inside each goroutine when it finishes.
  • Call Wait() to block until all goroutines are done.

Key Takeaways

Use sync.WaitGroup to wait for goroutines to finish safely.
Always call Add before starting goroutines and Done inside them.
Wait blocks until all goroutines signal completion with Done.
Forgetting Done causes Wait to block forever.
Use defer wg.Done() inside goroutines to ensure it runs.