Given this code:
package main
import (
"fmt"
"time"
)
func first(quit chan error) {
fmt.Println("1")
for {
select {
case <-quit:
fmt.Println("first quits")
return
default:
time.Sleep(20 * time.Millisecond)
}
}
}
func second(quit chan error) {
fmt.Println("2")
for {
select {
case <-quit:
fmt.Println("second quits")
return
default:
time.Sleep(20 * time.Millisecond)
}
}
}
func main() {
quit := make(chan error)
go first(quit)
go second(quit)
//something happens here, let's just simulate with a sleep
time.Sleep(500 * time.Millisecond)
close(quit)
time.Sleep(500 * time.Millisecond)
}
It seems that closing a channel correctly terminates two independent go routines. I thought channels were 1:1 communication paths, I was first trying to write an error
into the quit
channel but then only one of the go routines would be reading it. So I was reading all sorts of fan-out strategies until it occurred to me that closing the channel might just work.
Is closing the channel in this way the correct method to terminate independent go routines?
Reading from a closed channel always succeeds. Because of this, closing a channel is usually used to broadcast all goroutines that read from that channel that something has happened (timeout, cancel request, etc).
To answer your question: test, closing a channel is a correct way to let all goroutines know that it is time to terminate. That is what context.Context
does when it is canceled.