Issue
I am learning golang and have built a simple timer to understand how channels work:
package main
import (
"fmt"
"time"
)
func tick(tc chan time.Time, done chan bool) {
ticker := time.Tick(500 * time.Millisecond)
for {
select {
case <-done:
return
case tc <- <-ticker:
continue
}
}
}
func stop(done chan bool) {
time.Sleep(1600 * time.Millisecond)
done <- true
}
func main() {
tc := make(chan time.Time)
done := make(chan bool)
go tick(tc, done)
go stop(done)
for i := range tc {
fmt.Println(i)
}
fmt.Println("Ticker stopped")
panic("now")
}
It doesn’t quite work as expected. When you start it in go playground, it outputs a few timer lines (as expected) but it does not output Ticker stopped
or the stack trace resulted from calling panic
, and I don’t understand why. Any ideas?
Solution
for ... range
on a channel breaks when the channel is closed.
The program is blocks on for i := range tc { }
because tc
is never closed.
Fix by adding this line to the beginning of tick
:
defer close(tc)
Answered By – Zombo
Answer Checked By – Candace Johnson (GoLangFix Volunteer)