×

go · level 3 · unit 3 · lesson 4

  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

Closing a channel tells every listener at once: time to stop.

Sending a value wakes one receiver. Closing a channel wakes all of them, because a receive on a closed channel never waits. That makes close a : one call, and every goroutine listening hears it.

A channel used only as a signal carries no data, so give it the type chan struct{}. struct{} is the : a type with no fields, and its only value is written struct{}{}. Nothing travels down this channel except the news.

Workers listen for the signal with <-done, or inside a select with case <-done: return. Close done once, from the goroutine in charge, and every worker stops.

package main
import (
	"fmt"
	"strings"
	"sync"
)
func main() {
	done := make(chan struct{})
	stopped := make([]string, 3)
	var wg sync.WaitGroup
	for i := 0; i < 3; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			<-done
			stopped[i] = fmt.Sprint("worker ", i+1, " stopped")
		}(i)
	}
	close(done)
	wg.Wait()
	fmt.Println(strings.Join(stopped, "\n"))
}

A <-done on its own line waits for the signal and throws away the value it gets.