why in code below context cancel is received by both go routines but not ‘normal channel’ ?
channels are “point to point” so randomly one or the other goroutine receives from ch channel.
but why both goroutines receive ctx.Done() always ?
package main
import "sync"
import "fmt"
import "time"
import "context"
func main() {
var wg sync.WaitGroup
ch := make(chan struct{})
wg.Add(2)
ctx, cancel := context.WithCancel(context.Background())
go func() {
defer wg.Done()
fmt.Println("start goroutine 1")
for {
select {
case <- ch:
fmt.Println("got ch at goroutine 1")
case <- ctx.Done():
fmt.Println("got done goroutine 1")
return
}
}
}()
go func() {
defer wg.Done()
fmt.Println("start goroutine 2")
for {
select {
case <- ch:
fmt.Println("got ch at goroutine 2")
case <- ctx.Done():
fmt.Println("got done goroutine 2")
return
}
}
}()
time.Sleep(time.Second)
ch <- struct{}{}
time.Sleep(time.Second)
cancel()
fmt.Println("wait goroutines")
wg.Wait()
}
output:
apmattil@penguin:~/src/chan$ go run chan.go
start goroutine 1
start goroutine 2
got ch at goroutine 1
wait goroutines
got done goroutine 1
got done goroutine 2
apmattil@penguin:~/src/chan$ go run chan.go
start goroutine 2
start goroutine 1
got ch at goroutine 2
wait goroutines
got done goroutine 1
got done goroutine 2