Skip to content

Go Goroutines

A goroutine is a lightweight thread managed by the Go runtime. They are the core of Go's concurrency model, allowing you to run functions independently and simultaneously.

1. Basic Usage

To run a function in a goroutine, simply add the go keyword before the function call.

package main

import (
    "fmt"
    "time"
)

func f(from string) {
    for i := 0; i < 3; i++ {
        fmt.Println(from, ":", i)
    }
}

func main() {
    // 1. Direct call (synchronous)
    f("direct")

    // 2. Start a goroutine (asynchronous)
    go f("goroutine")

    // 3. Start a goroutine for an anonymous function
    go func(msg string) {
        fmt.Println(msg)
    }("going")

    // Wait for goroutines to finish (Basic approach)
    time.Sleep(time.Second)
    fmt.Println("done")
}

2. Synchronization (WaitGroups)

The time.Sleep approach is unreliable. In real apps, we use sync.WaitGroup to wait for all goroutines to finish correctly.

package main

import (
    "fmt"
    "sync"
)

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done() // Signal this worker is finished
    fmt.Printf("Worker %d starting\n", id)
}

func main() {
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1) // Tell WaitGroup we are starting 1 worker
        go worker(i, &wg)
    }

    wg.Wait() // Block until all workers call wg.Done()
}

Why use Goroutines over Threads?

  1. Memory: Goroutines start with only 2KB of stack memory, compared to 1MB or more for OS threads.
  2. Speed: Switching between goroutines (context switching) is much faster because it happens entirely within the Go runtime, not the OS kernel.
  3. Scalability: You can easily run hundreds of thousands of goroutines on a single machine where threads would crash it.

Best Practices

  • Don't leak them: Always make sure a goroutine has a way to finish.
  • No global state: Avoid modifying global variables from multiple goroutines (use channels or mutexes instead).
  • Channel communication: Prefer "communicating by sharing" (Channels) over "sharing by communicating" (Mutexes).