go · level 3 · unit 5 · lesson 1
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
A : a few goroutines share a long queue of jobs.
One goroutine per job is fine for ten jobs, but not for a million files or a server with limits. A worker pool starts a fixed number of goroutines, say 3. Each worker takes a job from a shared jobs channel, does it, sends the result on, and takes the next.
Once every job is queued, close the jobs channel, so each worker's range loop ends. main knows how many jobs it sent, so it receives exactly that many results, then it is done.
Workers finish in any order, so a report built from their results should be added up or sorted before it is printed. That gives the same report however the work was shared out.
package main
import "fmt"
func worker(jobs <-chan int, results chan<- int) {
for n := range jobs {
results <- n * n
}
}
func main() {
jobs := make(chan int, 5)
results := make(chan int, 5)
for w := 0; w < 3; w++ {
go worker(jobs, results)
}
for n := 1; n <= 5; n++ {
jobs <- n
}
close(jobs)
total := 0
for i := 0; i < 5; i++ {
total += <-results
}
fmt.Println("sum of squares:", total)
} Five jobs and three workers: the first workers to finish come back for the last two.
guess first
Two workers, three jobs, then a sort. What prints?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
jobs := make(chan string, 3)
results := make(chan string, 3)
for w := 0; w < 2; w++ {
go func() {
for name := range jobs {
results <- strings.ToUpper(name)
}
}()
}
for _, name := range []string{"pear", "fig", "lime"} {
jobs <- name
}
close(jobs)
got := []string{<-results, <-results, <-results}
sort.Strings(got)
fmt.Println(got)
}
your turn
Your turn. Run your own pool.
Choose how many workers to start, from 1 to 6, then fill in the call that tells the workers no more jobs are coming.
output
press run to see what happens
fix it
The packing report never comes. Can you fix it?
output
press run to see what happens
- It is a deadlock. How many results does
mainwait for, and how many jobs were there? - Four orders make four results, but
i <= len(orders)goes round five times. - Change
<=to<in the loop that receives the results.
nailed it
a few workers, a long queue, no chaos. :D
- A worker pool caps how many goroutines do the work.
- Close the jobs channel so every worker's
rangeends. - Receive one result per job, then add up or sort them.
new words in your collection
- worker pool
- worker
This lesson isn’t saved. A free account remembers every lesson you finish.