最佳调用具有可变执行时间功能在Golang最小间隔的方式?

问题描述 投票:1回答:1

我想在不超过在Go给定的时间间隔,通过一个调用开始时测量到下一次调用的开始少执行功能。函数本身将在其执行时间而变化。

如果函数超过预设的时间间隔运行,我想立即重新运行。但是,如果/当它最终重新开始,在不到一个完整的间隔完成,我希望它立即恢复等待,直到下一个区间的边界。

对于背景下,这是一个速率limiter--被调用的函数可以很容易地旋CPU,但它不会产生额外的价值,因为它与人类的谁也不可能反应这么快交互。

为清楚起见,一个示例(例如interval == 20ms中):

runtime:  15ms
wait:      5ms
runtime:  25ms
wait:      0ms
runtime:  25ms
wait:      0ms
runtime:  15ms
wait:      5ms <-- this is the important bit

如果我使用time.Ticker,我相信更多的“滴答”要么在Ticker.C通道排队(如果它的缓存),导致它做了一堆无延迟调用的时候恢复,还是北京时间的作家会阻塞写通道并最终与afterit恢复第一个调用的过长时间的延迟恢复。

现在我正在做一些数学,这是工作,但感觉像它可能是未成语:

minDurationBetweenRuns := time.Millisecond * 100
for {
    lastRunTime := time.Now()

    DO_STUFF_HERE()

    durationSinceLastRun := time.Now().Sub(lastRunTime)
    if durationSinceLastRun < minDurationBetweenRuns {
        sleepTime := minDurationBetweenRuns - durationSinceLastRun
        if sleepTime > minDurationBetweenRuns {
            sleepTime = minDurationBetweenRuns
        }
        time.Sleep(sleepTime)
    }
}
go timer
1个回答
4
投票

在写的问题,我记得,Golang源是超级容易阅读......想通我应该只是看傻了之前偷看。我很高兴我发现了什么:)

the source评论对time.Ticker说,如果蜱读者落在它后面会开始下降蜱而不是阻塞写通道(其中有1只缓冲)。这样做的效果是“正轨”东西找回来后,我们已经错过了一个或多个蜱。

实例证明:

package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.NewTicker(time.Millisecond * 50)
    for i := 0; i < 10; i++ {
        fmt.Printf("New invocation starting at %dms\n", time.Now().Round(time.Millisecond).Nanosecond()/int(time.Millisecond))
        if i%3 == 0 {
            fmt.Println("Executing for 25ms")
            time.Sleep(time.Millisecond * 25)
        } else {
            fmt.Println("Executing for 75ms")
            time.Sleep(time.Millisecond * 75)
        }
        fmt.Println("Waiting for ticker...")
        <-t.C
    }
    t.Stop()
}

输出:

New invocation starting at 0ms
Executing for 25ms
Waiting for ticker...
New invocation starting at 50ms
Executing for 75ms
Waiting for ticker...
New invocation starting at 125ms
Executing for 75ms
Waiting for ticker...
New invocation starting at 200ms
Executing for 25ms
Waiting for ticker...
New invocation starting at 250ms
Executing for 75ms
Waiting for ticker...
New invocation starting at 325ms
Executing for 75ms
Waiting for ticker...
New invocation starting at 400ms
Executing for 25ms
Waiting for ticker...
New invocation starting at 450ms
Executing for 75ms
Waiting for ticker...
New invocation starting at 525ms
Executing for 75ms
Waiting for ticker...
New invocation starting at 600ms
Executing for 25ms
Waiting for ticker...
© www.soinside.com 2019 - 2024. All rights reserved.