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.