我想制作一个有两个不同持续时间的倒计时器。做这个的最好方式是什么?我试着这样做:
s5 := time.Tick(5 * time.Second)
m5 := time.Tick(5 * time.Minute)
for {
select {
case t := <-s5:
...
case t := <-m5:
...
}
}
但我需要不同时间间隔的代码:
5:00 -> 0:00
0:05 -> 0:00
5:00 -> 0:00
0:05 -> 0:00
这是惯用的方法吗?
答案 0 :(得分:3)
如果你想要,你可以打电话给睡眠
dur := 1 * time.Second
nextDur := 3 * time.Second
for {
time.Sleep(dur)
dur, nextDur = nextDur, dur
...
}
如果您需要time.Timer
,请在select
中替换持续时间。这是我个人会坚持的,因为你不必担心由于调度不一致导致的两个定时器之间的偏移。
dur := 1 * time.Second
nextDur := 3 * time.Second
timer := time.NewTimer(dur)
for {
select {
case t := <-timer.C:
dur, nextDur = nextDur, dur
timer.Reset(dur)
...
}
...
}
或运行2个定时器偏移较小的间隔
dur1 := 1 * time.Second
dur2 := 3 * time.Second
timer1 := time.NewTimer(dur1)
timer2 := time.NewTimer(dur1 + dur2)
for {
select {
case t := <-timer1.C:
timer1.Reset(dur1 + dur2)
fmt.Println("timer1:", t)
case t := <-timer2.C:
timer2.Reset(dur1 + dur2)
fmt.Println("timer2:", t)
}
}
你还可以像你最初尝试的那样运行交错的代码,但这需要更多的协调来延迟其中一个的启动
dur1 := 1 * time.Second
dur2 := 3 * time.Second
ticker1 := time.NewTicker(dur1)
ticker2 := time.NewTicker(dur1 + dur2)
var once sync.Once
delayOnce := func() {
ticker1.Stop()
ticker1 = time.NewTicker(dur1 + dur2)
}
for {
select {
case t := <-ticker1.C:
once.Do(delayOnce)
fmt.Println("ticker1:", t)
case t := <-ticker2.C:
fmt.Println("ticker2:", t)
}
}
答案 1 :(得分:1)
一种解决方案是只有1个自动收报机,每5秒钟一次。 5分钟加5秒是61 * 5秒。那么&#34;期间&#34;是61蜱。每61th
个刻度线为5分钟标记,每61th+1
个刻度线为5秒标记。由于只有一个自动收报机,甚至不需要select
:
c, count := time.Tick(5*time.Second), 1
for {
<-c
count++
switch count % 61 {
case 0:
fmt.Println("5-min mark")
case 1:
fmt.Println("5-sec mark")
}
}
注意:由于count
初始化为1
,因此第一个&#34;任务&#34;将是5-min mark
,在开始后5分钟后执行。
另一个解决方案是使用一系列2 time.Sleep()
个调用,首先是5分钟,第二个是5秒:
for {
time.Sleep(5 * time.Minute)
fmt.Println("5-min mark")
time.Sleep(5 * time.Second)
fmt.Println("5-sec mark")
}
但是这个时间也取决于你执行的任务。因此要么使用第一个解决方案,要么在单独的goroutine中执行任务,这样他们就不会干扰时间,例如:
for {
time.Sleep(5 * time.Minute)
go func () {
fmt.Println("5-min mark")
}
time.Sleep(5 * time.Second)
go func () {
fmt.Println("5-sec mark")
}
}