Coding/Learn/go/go goroutines and runtime
Go Foundational Course
01.Introduction, Toolchain & Package main
02.Variables, Zero Values, Constants & iota
03.Control Flow: If with Init Statements & Switch
04.The Unified For Loop & Range Iteration
05.Functions, Multiple Return Values & Named Returns
06.Arrays vs Slices: Dynamic Memory & Headers
07.Maps: Key-Value Hash Tables & Safe Access
08.Pointers & Value vs Pointer Semantics
09.Structs, Receiver Methods & Composition
10.Implicit Interfaces & Duck Typing with Typesafety
11.Explicit Error Handling, Wrapping & Inspection
12.Defer, Panic & Recover: Resource Cleanup
13.Strings, Runes & UTF-8 Encoding Internals
14.Goroutines & The M:N Work-Stealing Scheduler
15.Channels: CSP Concurrency & Pipelines
16.Select Statement, Non-Blocking IO & Timeouts
17.Mutexes, RWMutex & Atomic Primitives
18.Context Propagation, Cancellation & Deadlines
19.JSON Serialization, Tags & net/http Routing
20.Capstone: High-Performance Concurrent Microservice Engine
Course Certificate0%

Complete all lessons to earn

LearnGoroutines & The M:N Work-Stealing Scheduler
14 / 20 0%
Lesson 14 of 20
15 mins read

Goroutines & The M:N Work-Stealing Scheduler

PreviousNext Lesson
In Plain English

Goroutines are ultra-lightweight concurrent execution units multiplexed onto OS threads by the Go runtime. Learn the "go" keyword, the M:N scheduler model (G, M, P), and sync.WaitGroup coordination.

The Mental Model

"Operating system threads are heavy 18-wheeler trucks. Goroutines are nimble electric scooters—you can launch 100,000 of them simultaneously on a laptop without running out of RAM."

Deep Dive: How It Works

The GMP Scheduler: Goroutines (G) are multiplexed onto OS threads (M) via logical processor contexts (P).

Dynamic 2KB Stacks: Goroutines start with only 2KB of memory and grow/shrink dynamically as required.

sync.WaitGroup: Coordinates termination of concurrent goroutines via Add(), Done(), and Wait().

Syntax Blueprint

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    doWork()
}()
wg.Wait()

Increment WaitGroup counter with Add(1), execute task in goroutine with go keyword, defer Done(), and block with Wait().

PointCore Rules to Remember

Point star
Ultra Lightweight: Starts at 2KB memory overhead per goroutine (vs 1-8MB for OS threads).
Point star
Work Stealing: Go runtime automatically distributes idle goroutines across available CPU cores.
Point star
Explicit Synchronization: main() does not wait for background goroutines; use sync.WaitGroup to block.

Common Beginner Traps & How to Fix Them

Mistake:Forgetting to call wg.Wait() in main, causing program to exit before workers execute.

Why it happens: Process termination exits all active goroutines instantly without waiting.

How to fix: Always call wg.Wait() before main returns.

Pro Tip: In Go 1.22+, loop variables are per-iteration scoped, eliminating the classic closure variable capture bug.

Live Interactive Example

Hit Run Code to see it live
Parallel Worker Dispatch with sync.WaitGroup
Go 1.22 / Runtime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Output Console
Click "Run Code" to view the rendered output.
How it works: sync.WaitGroup tracked 3 tasks with wg.Add(1) and blocked until all 3 called wg.Done().

Your Turn: Micro Challenge

No pressure! Edit the starter code below and test your solution with instant feedback.

Micro Exercise

Spawn 3 Concurrent Squarers

  • PointUse sync.WaitGroup to spawn 3 goroutines calculating squares of numbers 2, 4, 6.
  • PointEach goroutine should print "Square of [n]: [n*n]".
  • PointIn main(), initialize wg, call wg.Add(3), launch goroutines with wg.Done(), and wait with wg.Wait().
1
2
3
4
5
6
7
8
9
10
11
Sandbox Output
Click "Run & Check" to test your solution.

Finished reading and practicing?

Mark this lesson as completed to update your course progress.

PreviousNext Lesson
Overview100 SheetLearnCertificates