Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Launching Multiple Goroutines | Working with Goroutines and Channels
Concurrency in Go

bookLaunching Multiple Goroutines

Pyyhkäise näyttääksesi valikon

Launching Multiple Goroutines

In Go, you use goroutines to run code at the same time as other code. Launching more than one goroutine lets you perform several tasks concurrently, making your programs faster and more responsive. This is especially useful when you want to handle multiple requests, process data in the background, or make the most of your computer’s CPU cores.

You will learn how to start several goroutines at once and see how they work together. Understanding how to launch multiple goroutines is a key skill for building efficient, modern Go applications that can do many things at the same time.

Starting and Managing Multiple Goroutines

Launching more than one goroutine allows you to run several functions or tasks at the same time. In Go, you can start a new goroutine by using the go keyword before a function call. Each goroutine runs independently, but managing them safely requires careful coordination.

Launching Multiple Goroutines

To start several goroutines, call the go keyword in a loop or for each function you want to run concurrently:

go func1()
go func2()
for i := 0; i < 5; i++ {
    go worker(i)
}

Each call creates a new, lightweight thread of execution.

Synchronizing Goroutines

When you launch goroutines, you often need to know when they finish. Two common patterns for synchronization are:

Wait Groups

A sync.WaitGroup lets you wait for a group of goroutines to finish:

  • Create a WaitGroup variable;
  • Call Add(n) to set how many goroutines to wait for;
  • Each goroutine calls Done() when finished;
  • The main goroutine calls Wait() to block until all are done.

This pattern ensures your program does not exit before all goroutines complete.

Channels for Coordination

Channels can also signal when a goroutine is done:

  • Each goroutine sends a value to a channel when finished;
  • The main goroutine reads from the channel to track completion.

Channels are useful for passing results or errors back from goroutines.

Common Pitfalls: Race Conditions

A race condition happens when two or more goroutines access the same variable at the same time, and at least one of them writes to it. This leads to unpredictable results and bugs that are hard to find.

Avoid race conditions by:

  • Using channels to communicate between goroutines;
  • Protecting shared data with synchronization tools like mutexes;
  • Never sharing variables between goroutines unless you control access.

Always test your code with the -race flag to catch race conditions early.

main.go

main.go

copy
123456789101112131415161718192021222324
package main import ( "fmt" "sync" ) func printMessage(id int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("Goroutine %d is running.\n", id) } func main() { var wg sync.WaitGroup for i := 1; i <= 3; i++ { wg.Add(1) go printMessage(i, &wg) } wg.Wait() fmt.Println("All goroutines have finished.") }

Step-by-step explanation: launching multiple goroutines

You are looking at a Go program that launches several goroutines, coordinates their execution, and prevents race conditions. Here’s how it works, step by step:

1. Importing required packages

  • The fmt package is used for printing output;
  • The sync package provides synchronization primitives, such as WaitGroup.

2. Defining the main function

  • The main function is the entry point of every Go program.

3. Creating a WaitGroup

  • A variable of type sync.WaitGroup is created;
  • WaitGroup helps you wait for a collection of goroutines to finish executing.

4. Launching multiple goroutines

  • A for loop runs three times to start three goroutines;
  • On each loop iteration:
    • wg.Add(1) increments the WaitGroup counter by 1 before launching a goroutine;
    • A goroutine is started with the go keyword;
    • The goroutine receives a copy of the current loop variable (i) as an argument to avoid race conditions;
    • Inside the goroutine:
      • defer wg.Done() schedules the counter to decrease when the goroutine finishes;
      • The goroutine prints a message with its number.

5. Waiting for all goroutines to finish

  • After starting all goroutines, wg.Wait() is called;
  • This blocks the main function until the WaitGroup counter drops to zero, meaning all goroutines have finished.

6. Preventing race conditions

  • Passing the loop variable i as a function argument ensures each goroutine gets its own value, avoiding unexpected results.

Summary

  • You use goroutines to run code concurrently;
  • You synchronize them with a WaitGroup to ensure all work is complete before exiting;
  • You avoid race conditions by passing values safely to goroutines.

This approach is the foundation for safe concurrent programming in Go.

question mark

Which statements about launching multiple goroutines and synchronization are correct

Select all correct answers

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 2. Luku 1

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

Osio 2. Luku 1
some-alt