This is the 25th day of my participation in the August Challenge
This article appears in my column:Let’s Golang
Golang: Terminates and resets the timer
Today, let’s talk about the termination and reset of the timer.
Let’s start with the following code:
func main(a) {
timer := time.NewTimer(3 * time.Second)
fmt.Println(time.Now(),"Bomb will detonate in three seconds.")
timer.Stop()
fmt.Println("Time bomb defused, timer deactivated.")
t := <-timer.C
fmt.Println("The bomb was detonated.",t)
}
Copy the code
Let’s take a look at the results
2021- 08- 25 10:08:34.706412 +0800 CST m=+0.023017601The bomb will be3Two seconds later, the detonating time bomb has been defused. The timer is dead.Copy the code
We can use Stop to terminate the timer before its time is up. If the timer is stopped, its time pipeline will never read data. If it is forced to read, deadlock will occur. NewTimer(3 * time.second) is used to write data into the pipe.
Let’s look at an interesting example.
func main(a) {
timer := time.NewTimer(1 * time.Second)
fmt.Println(time.Now())
time.Sleep(2 * time.Second)
fmt.Println(time.Now())
timer.Reset(10*time.Second)
fmt.Println("The bomb was detonated.",<-timer.C)
}
Copy the code
Now, think about when the bomb went off!
Want to know the answer? Don’t worry, don’t worry. Take a break. Take a break
Let’s take a look at the results:
2021- 08- 25 10:15:16.8406335 +0800 CST m=+0.014999801
2021- 08- 25 10:15:18.906213 +0800 CST m=+2.080579301The bomb detonated2021- 08- 25 10:15:17.8522233 +0800 CST m=+1.026589601
Copy the code
Is that what you think it is? If not, that’s fine. Listen to me.
Because time.sleep() lets the main coroutine sleep while timer.c reads the pipe coroutine independently. So you put the main coroutine to sleep and it doesn’t affect the timer, it’s like a time bomb is about to detonate and you immediately set the time back on your watch, but the digital time on the time bomb doesn’t change the time back because of the time back on your watch.
Either! And then you would say I didn’t reset it?
However, if the timer expires, the reset will not work. If the time bomb has exploded, will it be effective if you reset it?
If we set the timer to 3 seconds, it looks like this:
timer := time.NewTimer(3 * time.Second)
Copy the code
So what’s the output?
2021- 08- 25 10:26:21.1299417 +0800 CST m=+0.020983301
2021- 08- 25 10:26:23.2191128 +0800 CST m=+2.110154401The bomb detonated2021- 08- 25 10:26:33.227692 +0800 CST m=+12.118733601
Copy the code
The main coprogram was Reset() 2 seconds after the timer was set, so the bomb exploded 12 seconds after the timer was set.
Interestingly, when I looked at the Reset() source code, I found this comment:
// Reset should be invoked only on stopped or expired timers with drained channels.
// If a program has already received a value from t.C, the timer is known
// to have expired and the channel drained, so t.Reset can be used directly.
// If a program has not yet received a value from t.C, however,
// The timer must be stopped and -- if Stop reports that the timer expired
// Before being stopped -- the channel fights explicitly:
//
// if !t.Stop() {
// <-t.C
/ /}
// t.Reset(d)
Copy the code
If the timer has expired and t.C. has been read, you can use Reset. If the program Reset has not read a value from t.C before, it needs to call Stop to terminate the timer before using Reset.