Part 1 , Part 2 , Part 3 , Part 4 , Part 5
Return values from go routines cannot be captured in the usual way with the =
operator because starting a go routine is non blocking. A channel can be used to collect the results from many concurrent go routines. Write a value to a channel inside the go routine that is doing the work, then in main()
read from the channel until it is closed to collect all the results from the go routines.
Playground: https://go.dev/play/p/_7WZdef4q4W
package main
import (
"fmt"
"sync"
)
func main() {
productChan := make(chan int)
wg := sync.WaitGroup{}
// use many goroutines to compute the product of two numbers
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
copyI, copyJ := i, j
wg.Add(1)
go func() {
defer wg.Done()
// send the product to an unbuffered channel
// this is a common pattern to fan in results from many goroutines
productChan <- copyI * copyJ
}()
}
}
// start a goroutine to wait for all the goroutines
// that are doing work to finish
// then close the channel to signal to main() that
// all the work is done
go func() {
wg.Wait()
// closing the channel will cause the range loop to exit
// this is a common pattern to signal the end of a channel
close(productChan)
}()
// read the products from the channel
// until the channel is closed
for product := range productChan {
fmt.Print(product, ",")
}
fmt.Println("Done")
}