Goroutines
An intro to Go concurrency — the go keyword, what makes a goroutine lightweight, and waiting for a group of goroutines with sync.WaitGroup.
2 questions
JuniorTheoryCommonWhat does the go keyword do in Go?
What does the go keyword do in Go?
go f() starts a goroutine — a lightweight, runtime-scheduled concurrent function. The call returns immediately and f runs independently of the caller, so the two proceed at the same time. Goroutines are multiplexed onto OS threads by the Go runtime, so you can launch thousands cheaply. When func main returns, the program exits and all still-running goroutines are stopped, so you must coordinate to wait for them.
Common mistakes
- ✗Thinking
go f()blocks the caller untilfreturns - ✗Assuming each goroutine costs a full OS thread
- ✗Forgetting that goroutines die when
func mainreturns
Follow-up questions
- →How do you make
mainwait for a goroutine to finish? - →Why are goroutines cheaper than OS threads?
JuniorTheoryCommonWhat is sync.WaitGroup and what is its Add/Done/Wait contract?
What is sync.WaitGroup and what is its Add/Done/Wait contract?
sync.WaitGroup waits for a set of goroutines to finish. It holds a counter: call Add(n) before starting the goroutines to raise it, call Done() (usually via defer) inside each goroutine to drop it by one, and call Wait() to block until the counter reaches zero. The key rule is to Add in the launching goroutine before the go statement, not inside the new goroutine, or Wait may return too early.
Common mistakes
- ✗Calling
Addinside the goroutine instead of beforego - ✗Forgetting to
defer wg.Done()so the counter never drops - ✗Copying a
WaitGroupby value instead of passing a pointer
Follow-up questions
- →What happens if
Doneis called more times thanAdd? - →How does a
WaitGroupdiffer from waiting on adonechannel?