Go Concurrency: Using sync.WaitGroup with Goroutines

Bartu Kocakara
2 min readNov 9, 2024

Go makes it easy to run tasks at the same time with its concurrency tools. One of these tools is sync.WaitGroup, which lets you run multiple tasks and wait for all of them to finish before moving on. This is useful for cases like preparing an airplane for takeoff, where you want to check multiple things—like lift, weight, drag, and thrust—before launching.

In this example, we’ll see how sync.WaitGroup can help us make sure all checks are done before liftoff. We'll also add a fun airplane animation to simulate the plane flying across the terminal when it's ready.

Why Use sync.WaitGroup?

When you run tasks at the same time, it’s important to wait until each one is complete. sync.WaitGroup lets you start several tasks, wait for all of them to finish, and then continue. This is helpful for making sure all parts of a job are complete before moving forward.

Code Example: Airplane Pre-flight Checks

Imagine we have an airplane and we need to check four things before it can take off:

  1. Lift: Check if there’s enough lift.
  2. Weight: Make sure the weight is balanced.
  3. Drag: Confirm drag is acceptable.
  4. Thrust: Verify the engines have enough thrust.

Here’s how we use sync.WaitGroup to make sure all these checks are done:

package mainimport (
"fmt"
"sync"
"time"
)
func lift(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("Lift is checked")
}
func weight(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("Weight is checked")
}
func drag(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("Drag is checked")
}
func thrust(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("Thrust is checked")
}
// Flight animation after checks
func flightAnimation() {
frames := []string{
"✈️ ", " ✈️ ", " ✈️ ",
" ✈️ ", " ✈️ ", " ✈️",
}
for i := 0; i < 3; i++ {
for _, frame := range frames {
fmt.Print("\r" + frame)
time.Sleep(100 * time.Millisecond)
}
}
fmt.Println("\nLiftoff!")
}
func main() {
var wg sync.WaitGroup
wg.Add(4)
go lift(&wg)
go weight(&wg)
go drag(&wg)
go thrust(&wg)
wg.Wait() // Wait for all checks
flightAnimation() // Show airplane animation
}

Explanation

sync.WaitGroup Setup:

We create a sync.WaitGroup called wg and set it to 4 because we have four checks.

Task Functions:

Each check (lift, weight, drag, thrust) runs in its own goroutine.Each function calls defer wg.Done() to signal it’s finished. This reduces wg by one each time a check completes.

Waiting for Completion:

wg.Wait() in main waits until all checks finish (when wg reaches zero).

Flight Animation:

After all checks, flightAnimation shows the plane moving across the terminal, simulating liftoff.

Output

You should see something like this:plaintext

Lift is checked
Weight is checked
Drag is checked
Thrust is checked
✈️
✈️
✈️
✈️
✈️
✈️
Liftoff!

Summary

Using sync.WaitGroup in Go is an easy way to wait for multiple tasks to finish before moving on. With this approach, you can manage multiple tasks, like airplane checks, in a clear, organized way. The flight animation adds a nice touch to show when all tasks are done and the plane can “take off.”

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Bartu Kocakara
Bartu Kocakara

Written by Bartu Kocakara

Senior Software Developer @sixttr

No responses yet

Write a response