×

go · level 3 · unit 4 · lesson 1

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. nailed it

Tap a green word if you get lost.

meet it

Two goroutines, one variable, at least one writing: a .

When two goroutines use the same variable at the same time and at least one of them writes, you have a data race. count++ looks like one step but is three: read, add one, write back. Two goroutines can both read 5 and both write 6, and one visit is lost.

Races are nasty because the program usually works. It passes on your laptop, then goes wrong on a busy server at 3am. Go ships a to catch them: on your own computer, run go run -race main.go or go test -race, and it reports every race it sees happen.

There are three cures. Do not share: give each goroutine its own slot. Lock: guard the variable with a mutex. Communicate: pass values over a channel, so only one goroutine ever touches the data.

package main
import (
	"fmt"
	"strings"
	"sync"
)
func main() {
	logs := []string{"home shop home", "blog", "home home shop"}
	counts := make([]int, len(logs))
	var wg sync.WaitGroup
	for i, log := range logs {
		wg.Add(1)
		go func(i int, log string) {
			defer wg.Done()
			counts[i] = strings.Count(log, "home")
		}(i, log)
	}
	wg.Wait()
	total := 0
	for _, c := range counts {
		total += c
	}
	fmt.Println("home visits:", total)
}

This program uses the first cure: every goroutine counts into its own slot, and only main adds them up.