Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何关闭计时器频道?_Go - Fatal编程技术网

Go 如何关闭计时器频道?

Go 如何关闭计时器频道?,go,Go,我有一个计时器,它会被某些事件重置。go函数使用范围监听频道。如何关闭通道,以便循环退出 func resetTimer(){ if rf.electionTimer != nil { rf.electionTimer.Stop() } } rf.electionTimer = time.NewTimer(electionTime) for _ = range rf.electionTimer.C { // Do someth

我有一个计时器,它会被某些事件重置。go函数使用范围监听频道。如何关闭通道,以便循环退出

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

rf.electionTimer = time.NewTimer(electionTime) 


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

使用一个通道来发出环路应该退出的信号

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
        }
    }
循环:
为了{
挑选{
案例t:=来自的通道不会多次输出时间。它只会在计时器结束后输出一次时间。因此,在
for
循环中使用
rf.electionTimer
是无用的

尝试将
for
循环替换为:

t := <-rf.electionTimer.C
// Do something with t

time.Timer只会触发一次,因此实际上不需要在它上面设置范围。你是想使用time.Ticker吗?@ardent过期的计时器可以重置,这意味着它实际上可以触发多次(与Ticker不同,如果控制代码需要,它可以不定期地触发)正如霍布斯所提到的,我使用了随机间隔和定时器重置。用一个简单的
bool
而不是
chan结构{}来代替rf.done可能会更有效率和意义
@acid,当从另一个goroutine调用Stop和Reset时引入数据竞争。谢谢,Cerise Limon。我正在重置计时器。我尝试了与您编写的类似的方法,但我使用了bool类型的通道,它在我尝试rf时阻塞了通道。完成@2ank3th发送到通道可以工作,但我无法确定为什么不工作为您工作时不会看到更多代码。我最初的解决方案是使用t:=
rf.electionTimer.Reset(0)