What is Go routine(Green Thread)

A goroutine is a lightweight Green thread managed by the Go runtime.
Memory is allocated on Process's Heap for go routines. Check Go Process Memory Layout

Code

Hello World


package main
import (
    "fmt"
    "time"
)
func sayHello() {
    fmt.Println("Hello from goroutine!")
}
func main() {
    go sayHello()       // Start a goroutine
    fmt.Println("Hello from main!") // Print from the main goroutine
    // Sleep for a while to allow the goroutine to execute
    time.Sleep(time.Second)
}
$ go run main.go
Hello from main!
Hello from goroutine!
      

2 Threads executing 1 function

Code Description

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	wg.Add(2)               // 2 goroutines. internal counter=2

	task := func(id int) {  // defer executes when scope ends
		defer wg.Done()       // Decrement counter when task finishes
		fmt.Printf("Goroutine %d is running\n", id)
	}

	// Launch 2 goroutines executing the task
	go task(1)
	go task(2)

	wg.Wait() // Wait for both to complete
}
      
sync.waitgroup = join() in C++
- Provided by Go to synchronize the execution of a group of goroutines. A WaitGroup creates a threadsafe shared counter, whose value is decreamented and once value reaches 0
- How it works?
  wg.Add(2); Create shared counter value=2
  goroutine finishes wg.Done() decrements it by 1(defer make wg.Done())
  wg.Wait() method in main waits until counter=0
defer?

Memory Leak in goroutine

Memory allocated to goroutine: Around 2k bytes of Stack is allocated to goroutines by Go runtime at time of creation and this memory grows/shrinks dynamically.
When goroutine dies then this memory is taken back by go runtime(ie no leak).
How leak happens in goroutine? Memory leak in goroutine means go runtime fails to cleanup the goroutine and hence fails to claim back this allocated memory(2k bytes or more).
Leak Condition:
- When no reciever is present on unbuffered channel, then that goroutine which is sending data on channel and channel are not Garbage collected by Go runtime.
- Memory allocated to goroutine + memory allocated to go channel is leaked.

              ---Unbufferd channel---
                                    /\
                                     |
                              goroutine sends data
        
How to avoid Memory leak? Use buffered channel

Bounded go routines

By default, Go makes it easy to spawn thousands of goroutines.
And each goroutine consumes memory or network handles, spawning them without a limit (unbounded) can lead to Out of Memory (OOM) errors or CPU exhaustion.
Bounded goroutines ensure only a fixed number of goroutines run at once
We can implement bounded goroutines using 2 patterns:
1. Semaphore OR
2. Worker Pool

1. Semaphore based bounded goroutines

Use a buffered channel with limit on number of values it can hold.

Max number of goroutines

Maximum limits depends on system's hardware resources and configurations.