intermediate Step 9 of 15

Goroutines and Concurrency

Go Programming

Goroutines and Concurrency

Concurrency is one of Go's defining features. Goroutines are lightweight threads managed by the Go runtime that enable you to run thousands — even millions — of concurrent tasks efficiently. Unlike OS threads that consume megabytes of memory each, goroutines start with just a few kilobytes of stack space that grows as needed. Launching a goroutine is as simple as adding the go keyword before a function call. This makes concurrent programming in Go accessible and practical for everyday tasks like handling multiple HTTP requests, processing data pipelines, or performing I/O operations in parallel.

Goroutines

package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("Worker %d starting\n", id)
    time.Sleep(time.Second)
    fmt.Printf("Worker %d done\n", id)
}

func main() {
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker(i, &wg)
    }

    wg.Wait()  // Wait for all goroutines to finish
    fmt.Println("All workers completed")
}

Mutex for Shared State

type SafeCounter struct {
    mu sync.Mutex
    count map[string]int
}

func (c *SafeCounter) Increment(key string) {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.count[key]++
}

func (c *SafeCounter) Get(key string) int {
    c.mu.Lock()
    defer c.mu.Unlock()
    return c.count[key]
}
Pro tip: Use sync.WaitGroup to wait for a group of goroutines to finish, and sync.Mutex to protect shared state. Prefer channels over mutexes when possible — Go's motto is "Do not communicate by sharing memory; share memory by communicating."

Key Takeaways

  • Goroutines are lightweight concurrent functions launched with the go keyword.
  • Use sync.WaitGroup to coordinate goroutine completion.
  • Use sync.Mutex to protect shared data from race conditions.
  • Go can handle millions of goroutines efficiently with minimal memory overhead.
  • Run go run -race main.go to detect data races during development.