SoFunction
Updated on 2025-03-04

Termination and reset implementation of Golang timer

Yesterday, some readers had questions about the termination of the timer. Today, let’s talk about the termination and reset of the timer!

A timer is a mechanism that performs a task at some point in the future by setting it up.

There are usually only two types of timers, one is the delay mode that only executes once, and the other is the interval mode that executes once every period of time.

In modern programming languages, timers are almost standard. In addition to setting the timer, there is also a method to provide a timer.

For example, in JavaScript, four APIs are provided: setTimeout, setInterval, clearTimeout and clearInterval, which is relatively simple. The timer API in Go is relatively complete, and all APIs are in the time package.

Let's first look at the following code:

func main() {
    timer := (3 * )
    ((),"The bomb will detonate in 3 seconds")
​
​
    ()
    ("The time bomb has been removed, the timer has failed")
​
    
    t := <-
    ("The bomb detonates",t)
}

Let's take a look at the running results first

2021-08-25 10:08:34.706412 +0800 CST m=+0.023017601 The bomb will explode in 3 seconds
Time bomb has been removed, timer has failed
fatal error: all goroutines are asleep - deadlock!

We can use Stop to terminate the timer while the timer time has not arrived. If the timer has been stopped, its time pipeline will never read the data. If it is forced to read, a deadlock will occur. Because using Stop means stop writing data into the pipeline, or it can be said that the data in the pipeline has been read, using (3 * ) means writing data into the pipeline.

Let's look at an interesting example.

func main()  {
    timer := (1 * )
    (())
​
    (2 * )
    (())
​
    (10*)
    ("The bomb detonates",<-)
}

Now, think about when the bomb detonated!

Want to know the answer? Don't worry, don't worry, take a break, take a break, the answer will be revealed immediately

Let's take a look at the running results:

2021-08-25 10:15:16.8406335 +0800 CST m=+0.014999801
2021-08-25 10:15:18.906213 +0800 CST m=+2.080579301
The bomb detonated on 2021-08-25 10:15:17.8522233 +0800 CST m=+1.026589601

Is it the same as you think? If not, it doesn't matter, listen to me in detail.
Because () is to let the main coroutine sleep, and the coroutine of the read pipeline is independent. So if you let the main coroutine sleep well, it will not affect the timer timing. It is equivalent to a time bomb detonating. You immediately adjust the time of the watch back, but the digital time on the time bomb will not adjust the time back due to the time on the watch.

Alas! At this time, you will say that I have not reset it?
But if the timer timed out, then the reset will not work. Think about it, the time bombs have exploded. Is it still effective if you reset it?
If we set the timer to 3 seconds, that's it:

timer := (3 * )

So what will the output result?

2021-08-25 10:26:21.1299417 +0800 CST m=+0.020983301
2021-08-25 10:26:23.2191128 +0800 CST m=+2.110154401
The bomb detonated on 2021-08-25 10:26:33.227692 +0800 CST m=+12.118733601

2 seconds after setting the timer, the main coroutine will execute Reset(), so the bomb will explode after setting the timer for 12 seconds.
Interestingly, when I looked at the source code of Reset(), I found a comment like this:

// Reset should be invoked only on stopped or expired timers with drained channels.
// If a program has already received a value from , the timer is known
// to have expired and the channel drained, so  can be used directly.
// If a program has not yet received a value from , however,
// the timer must be stopped and—if Stop reports that the timer expired
// before being stopped—the channel explicitly drained:
//
//  if !() {
//      <-
//  }
//  (d)

According to my understanding, the general idea is that if the timer has expired and has been read, you can use Reset directly. If the program Reset has not read the value from it before, you need to call Stop to end the timer before using reset.

This is the end of this article about the termination and reset implementation of Golang timer. For more related content on Golang timer, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!