我编写了一段代码,创建了一个长度为0的计时器,并且它不会立即过期(这是我所期望的)。短暂的睡眠通话确实会使它过期,但是我对原因感到困惑。
我关心的原因是,使用此思想的代码包含一个代码段,该代码段在发生低概率错误时返回0,并认为应将计时器设置为立即过期,然后重试函数。我不认为这里需要的纳秒级睡眠会影响我的实现,但会困扰我。
我做错了吗,这是预期的行为吗?
谢谢!
package main
import (
"fmt"
"time"
)
func main() {
testTimer := time.NewTimer(time.Duration(0) * time.Millisecond)
fmt.Println(Expired(testTimer))
time.Sleep(time.Nanosecond)
fmt.Println(Expired(testTimer))
}
func Expired(T *time.Timer) bool {
select {
case <-T.C:
return true
default:
return false
}
}
游乐场链接:https://play.golang.org/p/xLLHoR8aKq
打印
false
true
最佳答案
time.NewTimer()
不保证最长等待时间。它仅保证最短的等待时间。引用其文档:
因此,将零持续时间传递给time.NewTimer()
,返回的 time.Timer
不会立即“过期”也就不足为奇了。
如果实现将检查传递的持续时间是否为零,并且在返回之前在计时器的 channel 上发送值,则返回的计时器可能立即“过期”。相反,它会像在任何给定持续时间内一样正常地启动内部计时器,该计时器将负责在其 channel 上发送值,但仅在将来的某个时间发送。
请注意,在有多个CPU内核且 runtime.GOMAXPROCS()
大于1的情况下,在time
返回之前,另一个goroutine(在NewTimer()
包内部)在计时器 channel 上发送值的可能性很小,但这是很小的机会...另外由于这是实现细节,因此将来的版本可能会添加此“优化”以检查传递的持续时间是否为0,并按您期望的方式运行,但是与所有实现细节一样,不要指望它。依靠记录在案的内容,别再期待了。
关于go - 长度为0的Golang计时器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43616295/