我有一个由某些事件重置的计时器。 go函数使用range监听通道。如何关闭通道以便循环退出?
func resetTimer(){
if rf.electionTimer != nil {
rf.electionTimer.Stop()
}
}
rf.electionTimer = time.NewTimer(electionTime)
for _ = range rf.electionTimer.C {
// Do something
}
答案 0 :(得分:3)
使用通道在循环退出时发出信号。
rf.done := make(chan struct{})
rf.electionTimer = time.NewTimer(electionTime)
func stopTimer(){
if rf.electionTimer != nil {
rf.electionTimer.Stop()
close(rf.done)
}
}
在循环中选择信号通道和定时器通道。信号通道关闭时中断循环。
loop:
for {
select {
case t := <-rf.electionTimer.C:
// Do something
case <-rf.done:
break loop
}
}
请注意,如果应用程序未在计时器上调用Reset,则在问题或此答案中使用循环是没有意义的。如果未重置定时器,则只有一个值将被发送到定时器的通道。
答案 1 :(得分:0)
来自timer的频道不会多次输出时间。定时器结束后,它只会输出一次。因此,在rf.electionTimer
循环中使用for
毫无用处。
尝试使用以下代码替换for
循环:
t := <-rf.electionTimer.C
// Do something with t
这将暂停执行,直到计时器停止。
请注意,使用rf.electionTimer.Stop()
会阻止计时器结束,而<-rf.electionTimer.C
行会冻结。
如何关闭通道以便循环退出?
为防止<-rf.electionTimer.C
阻止执行代码,建议您使用:
rf.electionTimer.Reset(0)