Back

Exploring Goroutines in Go

Nikita Khabya

Nikita Khabya

6 min read

|

4 months ago

Goroutines are Go's fundamental building blocks for concurrent programming, allowing multiple pieces of logic to execute simultaneously while providing elegant communication mechanisms between them.

In programming, when we need to handle multiple operations at once, we typically talk about two concepts: Concurrency and Parallelism. Let’s explore what each means.

What is Concurrency?

What is Parallelism?

Difference between Concurrency and Parallelism?

What is a goroutine? πŸ”€

How does a goroutine work? πŸ“Š

Goroutine Execution

What is WaitGroup? ⏳

Methods of WaitGroup βš™οΈ


What is defer?

  • Defer is a keyword in Go that allows us to delay the execution of a function until the surrounding function returns.
  • It is commonly used with WaitGroup to ensure that the Done() method is called when the goroutine finishes executing, even if an error occurs. This way, we can ensure that the WaitGroup counter is decremented correctly and the main process can exit safely.

How does WaitGroup work?

When we create a WaitGroup, it starts with a counter of zero.

go
wg := sync.WaitGroup{}

When we add a goroutine, we call the Add() method to increment the counter by 1.

go
wg.Add(1)

When the goroutine finishes executing, it calls the Done() method to decrement the counter by 1.

go
wg.Done()

The main process can call the Wait() method to block until the counter reaches zero, indicating that all goroutines have finished executing.

go
wg.Wait()

Example of using goroutines and WaitGroup

go
func main() {
	var wg sync.WaitGroup 

	wg.Add(1) 
	go func() {
		defer wg.Done() 
		fmt.Println("Executing 1st goroutine")
	}() 

	wg.Add(1) 
	go func() {
		defer wg.Done()
		fmt.Println("Executing 2nd goroutine")
	}()

	wg.Wait() 
	fmt.Println("All goroutines finished executing")
}

Explanation of the code: πŸ“

  1. Create a WaitGroup that will be used to wait for goroutines to finish
  2. Increment the WaitGroup counter by 1 for the first goroutine
  3. Decrement the WaitGroup counter by 1 when this goroutine finishes
  4. This is an anonymous function, so we need to invoke it immediately
  5. Increment the WaitGroup counter by 1 for the second goroutine
  6. Wait for all goroutines to finish executing

Order of execution: ⏰

Output X:

Executing 1st goroutine
Executing 2nd goroutine
All goroutines finished executing

Output Y:

Executing 2nd goroutine
Executing 1st goroutine
All goroutines finished executing

TL;DR: 🀝