测量执行时间,如果golang时间过长,则停止等待

Max*_*mov 2 go

我正在尝试测量funcWithUnpredictiveExecutionTime函数的执行时间。

func measureTime(expectedMs float64) (ok bool) {
    t1 := time.Now()
    funcWithUnpredictiveExecutionTime()
    t2 := time.Now()
    diff := t2.Sub(t1)
Run Code Online (Sandbox Code Playgroud)

funcWithUnpredictiveExecutionTime工作速度比我预期的快时,测量就可以了 。但是,如果它的速度慢于expectedMs 预期的毫秒数,测量将不会立即停止。

funcWithUnpredictiveExecutionTime工作时间长于expectedMs不等待funcWithUnpredictiveExecutionTime完成就可以停止时间测量吗?

换句话说,无论如何measureTime(200)都要返回200 ms好坏的结果。

我想我应该使用频道,然后以某种方式取消等待频道。但是如何做到这一点呢?

完整代码:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

// random number between min and max
func random(min, max int) int {
    rand.Seed(time.Now().Unix())
    return rand.Intn(max-min) + min
}

// sleeps for a random milliseconds amount between 200 and 1000
func funcWithUnpredictiveExecutionTime() {
    millisToSleep := random(200, 1000)
    fmt.Println(fmt.Sprintf("Sleeping for %d milliseconds", millisToSleep))
    time.Sleep(time.Millisecond * time.Duration(millisToSleep))
}

// measures execution time of a function funcWithUnpredictiveExecutionTime
// if expectedMs < actual execution time, it's ok.
// if expectedMs milliseconds passed and funcWithUnpredictiveExecutionTime
// still did not finish execution it should return
// without waiting for funcWithUnpredictiveExecutionTime
func measureTime(expectedMs float64) (ok bool) {
    t1 := time.Now()
    funcWithUnpredictiveExecutionTime()
    t2 := time.Now()
    diff := t2.Sub(t1)
    actualMs := diff.Seconds() * 1000
    ok = actualMs < expectedMs
    fmt.Println(actualMs)
    return
}

// prints results: Ok or too late
func printTimeResults(ok bool) {
    if ok {
        fmt.Println("Ok")
    } else {
        fmt.Println("Too late")
    }
}

func main() {
    printTimeResults(measureTime(200))  // expect it to finish in 200 ms anyway
    printTimeResults(measureTime(1000)) // expect it to finish in 1000 ms anyway
}
Run Code Online (Sandbox Code Playgroud)

输出:

Sleeping for 422 milliseconds
424.11895200000004
Too late
Sleeping for 422 milliseconds
425.27274900000003
Ok
Run Code Online (Sandbox Code Playgroud)

操场

Jim*_*imB 5

您无法取消goroutine,除非您将其设计为取消。您可以通过使用一个通道来通知正在计时的功能完成,从而使计时功能短路:

func measureTime(expectedMs float64) (ok bool) {
    done := make(chan struct{})
    t1 := time.Now()

    go func() {
        funcWithUnpredictiveExecutionTime()
        close(done)
    }()

    select {
    case <-done:
        ok = true
    case <-time.After(time.Duration(expectedMs) * time.Millisecond):
    }

    fmt.Println(time.Since(t1))
    return ok

}
Run Code Online (Sandbox Code Playgroud)

  • @DenysSéguret:它保证`measureTime`将立即停止。您不能停止`funcWithUnpredictiveExecutionTime`。没有任何类型的取消api,它就会阻塞,因此它必须运行到完成。 (3认同)