为了账号安全,请及时绑定邮箱和手机立即绑定

以不同的持续时间重复倒计时

以不同的持续时间重复倒计时

Go
繁星coding 2021-12-07 16:36:52
这些“功能”以相同的方式运行,实际上它们的调用方式几乎相同。该方法被称为方法表达式,接收者作为第一个参数:var s Square// The method calls.SetSide(5)// is equivalent to the method expression(*Square).SetSide(&s, 5)该SetSide方法也可以用作方法值来满足函数签名func(int),而SetSquareSide不能。var f func(int)f = a.SetSidef(9)这是在方法集Square满足接口的明显事实之上interface {    SetSide(int)}
查看完整描述

2 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

如果你愿意,你可以打电话给 sleep


dur := 1 * time.Second

nextDur := 3 * time.Second


for {

    time.Sleep(dur)

    dur, nextDur = nextDur, dur


    ...

}

或者,time.Timer如果需要,可以交替使用 a 中的持续时间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)

    }


}

你也可以像最初尝试的那样运行交错的 Tickers,但这需要更多的协调来延迟其中一个的启动


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)

    }


}


查看完整回答
反对 回复 2021-12-07
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

一种解决方案是只有 1 个每 5 秒滴答一次的股票代码。5分钟加5秒就是61*5秒。所以“周期”是 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,第一个“任务”将是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")

}

但是这个时间也取决于你执行的任务。所以要么使用第一个解决方案,要么在单独的 goroutines 中执行任务,这样它们就不会干扰时间,例如:


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")

    }

}


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 202 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信