Reputation: 465
I have a fairly simple program, which is supposed to self-terminate after a specified duration of time (for example, one second)
The code:
package main
import (
"fmt"
"time"
)
func emit(wordChannel chan string, done chan bool) {
defer close(wordChannel)
words := []string{"The", "quick", "brown", "fox"}
i := 0
t := time.NewTimer(1 * time.Second)
for {
select {
case wordChannel <- words[i]:
i++
if i == len(words) {
i = 0
}
// Please ignore the following case
case <-done:
done <- true
// fmt.Printf("Got done!\n")
close(done)
return
case <-t.C:
fmt.Printf("\n\nGot done!\n\n")
return
}
}
}
func main() {
mainWordChannel := make(chan string)
// Please ignore mainDoneChannel
mainDoneChannel := make(chan bool)
go emit(mainWordChannel, mainDoneChannel)
for word := range mainWordChannel {
fmt.Printf("%s ", word)
}
}
I compile and execute the binary, and you can see the execution here.
That is clearly above 1 second.
Go's documentation on NewTimer
reads this:
func NewTimer
func NewTimer(d Duration) *Timer
NewTimer creates a new Timer that will send the current time on its channel after at least duration d.
Can someone kindly help me understand what's happening here? Why isn't the program terminating exactly (or closely at least
) after 1 second?
Upvotes: 2
Views: 658
Reputation: 94
Timer works as intended. It sends a value to a channel. I think it is useful to read about select statement Each iteration in your loop can write to a channel. If > 1 communication can proceed there is no guarantee which are. So, if add delay to read loop like this :
for word := range mainWordChannel {
fmt.Printf("%s ", word)
time.Sleep(time.Millisecond)
}
In this case, only read from timer.C
can proceed. And program will end.
Upvotes: 4