Go Tutorial · Concurrency · Lesson 24 of 30
Go Channels and select
Send values between goroutines, buffered channels, range over channels and select.
Channels
A channel is a typed pipe between goroutines. ch <- v sends; v := <-ch receives. An unbuffered send waits until someone receives:
package main
import "fmt"
func main() {
ch := make(chan string)
go func() {
ch <- "ping"
}()
fmt.Println(<-ch)
nums := make(chan int, 3) // buffered: holds 3 values without a receiver
for i := 1; i <= 3; i++ {
nums <- i * 10
}
close(nums) // no more values
for n := range nums {
fmt.Println(n)
}
}
Output
ping 10 20 30
Run this on your computer — see “Get Started” for setup.
"Don't communicate by sharing memory; share memory by communicating."
Worker pools
A classic pattern: jobs go into one channel, workers process them, results come out of another:
package main
import (
"fmt"
"slices"
"sync"
)
func main() {
jobs := make(chan int)
results := make(chan int)
var wg sync.WaitGroup
for range 3 { // 3 workers
wg.Add(1)
go func() {
defer wg.Done()
for n := range jobs {
results <- n * n
}
}()
}
go func() {
for i := 1; i <= 5; i++ {
jobs <- i
}
close(jobs)
}()
go func() {
wg.Wait()
close(results)
}()
var squares []int
for r := range results {
squares = append(squares, r)
}
slices.Sort(squares) // workers finish in any order
fmt.Println(squares)
}
Output
[1 4 9 16 25]
Run this on your computer — see “Get Started” for setup.
select
select waits on several channel operations at once — great for timeouts:
package main
import (
"fmt"
"time"
)
func main() {
fast := make(chan string)
go func() {
time.Sleep(20 * time.Millisecond)
fast <- "fast result"
}()
slow := make(chan string)
go func() {
time.Sleep(2 * time.Second)
slow <- "slow result"
}()
for _, ch := range []chan string{fast, slow} {
select {
case v := <-ch:
fmt.Println(v)
case <-time.After(200 * time.Millisecond):
fmt.Println("timed out")
}
}
}
Output
fast result timed out
Run this on your computer — see “Get Started” for setup.
Test yourself
What does close(ch) signal?
The channel is deletedNo more values will be sentReceivers must stop immediatelyThe buffer is cleared
Show answer
Answer: No more values will be sent