Skip to content
Goroutines
step 1/5

Reading — step 1 of 5

Learn

~3 min readGoroutines and Channels

Goroutines

A goroutine is a function running concurrently with the rest of your program, scheduled by the Go runtime instead of the operating system. Starting one costs a few kilobytes of stack, so hundreds of thousands are routine. The syntax is one keyword:

go

The runtime multiplexes goroutines onto a small pool of OS threads. You never manage threads; you just say go.

Trap 1: main does not wait

When main returns, the program exits — running goroutines are killed mid-flight, silently:

go

time.Sleep "fixes" this in demos and is wrong everywhere else: too short and you lose work, too long and you waste time. The real tool is sync.WaitGroup, a counter you can block on:

go

Add must happen before the go statement. If the goroutine itself calls Add, then Wait can run first, see a zero counter, and return while the work is still pending.

Trap 2: the loop variable

Notice func(n int) { ... }(i) — the loop variable is passed as an argument. On the Go version this grader runs, every closure in a loop shares ONE i; by the time a goroutine actually executes, the loop has usually finished and each goroutine sees the final value. Passing i as a parameter gives each goroutine its own copy. (Go 1.22 changed loop-variable scoping, but write the portable form.)

Trap 3: shared state races

Two goroutines executing total += x at the same time is a data race: the read-modify-write sequences interleave and updates get lost. The result is nondeterministic — the worst kind of bug, because it usually passes. Guard shared variables with a mutex:

go

Locally you can catch races with go test -race ./... or go run -race main.go. Lesson 5.2 covers the sync toolbox in depth; today you need exactly this much: a WaitGroup to wait, a Mutex to guard total.

Your exercise

Read N, then a line of N space-separated ints. Split the slice into 4 chunks, sum each chunk in its own goroutine, add each partial into total under the mutex, wg.Wait(), then print the total.

Chunk with ceiling division and clamp the bounds:

go

Mistakes the grader will catch:

  1. chunk := n / 4 with small N. The hidden test is N=1, input 42. Integer division gives chunk 0, every slice is empty, and you print 0 instead of 42.
  2. Printing before wg.Wait(). The goroutines have not added their partials yet, so you print 0 — the starter's placeholder bug made permanent.
  3. Skipping the mutex. 15 and 360 will usually still come out right — that is what makes races vicious — but the code is wrong, and under -race it lights up immediately.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…

Goroutines — Go Intermediate