如何关闭计时器通道?

时间:2017-12-05 06:25:55

标签: go

我有一个由某些事件重置的计时器。 go函数使用range监听通道。如何关闭通道以便循环退出?

func resetTimer(){
        if rf.electionTimer != nil {
             rf.electionTimer.Stop()
        }
}

rf.electionTimer = time.NewTimer(electionTime) 


for _ = range rf.electionTimer.C {
  // Do something
}

2 个答案:

答案 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)