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

超时未触发

超时未触发

Go
守着星空守着你 2021-10-25 16:56:45
为了好玩,我在 Go 中实现了一些排序算法,现在我想测试它们在随机整数上的性能。所以我写了下面的程序。我遵循了类似的格式:https : //gobyexample.com/timeouts但是,超时似乎没有正确触发。下面是我的代码:package mainimport (    "allanpinkerton.com/algorithms/sorting"    "fmt"    "math/rand"    "os"    "strconv"    "time")// Prints out the time elapsed since startfunc timeExecution(startTime time.Time, functionName string, inputSize int) string {    executionTime := time.Since(startTime)    return fmt.Sprintf("%-20s took %10.4fms to sort %d elements\n", functionName, float64(executionTime.Nanoseconds())/1000000, inputSize)}// Generates file with n random ints named integerArray + nfunc generateRandomIntegers(n int, filename string) {    arr := make([]int, n)    for i := 0; i < n; i++ {        arr[i] = rand.Int()    }    f, _ := os.Create(filename)    defer f.Close()    for _, num := range arr {        f.WriteString(strconv.Itoa(num) + " ")    }    f.WriteString("\n")    f.Sync()    fmt.Printf("Generated " + filename + " with " + strconv.Itoa(n) + " elements.\n")}func checkError(err error) {    if err != nil {        panic(err)    }}func main() {    sortingFunctions := map[string]interface{}{        "InsertionSort":        sorting.InsertionSort,        "QuickSortLastElement": sorting.QuickSortLastElement,        "QuickSortRandom":      sorting.QuickSortRandom,    }    if len(os.Args) != 2 {        fmt.Printf("No size specified.\n")        return    }    size := os.Args[1]    sizeInt, err := strconv.Atoi(size)    checkError(err)    arr := make([]int, sizeInt)    for i := 0; i < sizeInt; i++ {        arr[i] = rand.Int()    }问题就解决了。所以是我的自定义排序函数阻止了超时被触发。有什么我必须添加到这些函数中才能使它们并行运行的吗?这是一个连接版本,其中包含 Playground 中的所有代码。 https://play.golang.org/p/SBgDTGyUyp
查看完整描述

2 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

由于您time.After(time.Second)在最终循环内使用,因此每次结果到达时都会重置超时。相反,尝试


timeoutChannel := time.After(time.Second)

for _ = range sortingFunctions {

    select {

    case result := <-mainChannel:

        fmt.Printf(result)

    case <-timeoutChannel:

        fmt.Println("Timeout")

    }

}

上面的代码现在可以正确捕获超时。它仍然没有按预期工作,因为循环的内容总是执行三次(因为sortingFunctions有三个元素),并且任何超时都计入这三次迭代。使用 go playground 中的代码,我现在得到以下输出:


Generated 90000 integers.

QuickSortRandom      took     9.4268ms to sort 90000 elements

Timeout

QuickSortLastElement took     8.6096ms to sort 90000 elements


查看完整回答
反对 回复 2021-10-25
?
慕森卡

TA贡献1806条经验 获得超8个赞

您在 Go playground 上发布的代码给出了以下输出:


Generated 90000 integers.

InsertionSort        took  4465.6230ms to sort 90000 elements

QuickSortLastElement took    11.2758ms to sort 90000 elements

QuickSortRandom      took    11.6547ms to sort 90000 elements

我怀疑您没有看到超时被调用的事实是由于InsertionSort确实进行了任何函数调用,因此不允许调度程序在 goroutines 之间切换。由于 Go 默认只使用一个线程,所以其他一切都必须等到InsertionSort完成。


为了验证这个假设,我尝试使用 GOMAXPROCS=4 调用程序(允许 Go 调度程序使用 4 个操作系统线程):在这种情况下,我得到了输出


Generated 90000 integers.

QuickSortRandom      took    21.1900ms to sort 90000 elements

QuickSortLastElement took    11.4538ms to sort 90000 elements

Timeout

正如预期的那样。(奇怪的是,对于 GOMAXPROCS=2,行为不是确定性的,有时会触发超时,有时不会。我没有试图找出为什么 2 个线程在这里并不总是足够的。)


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

添加回答

举报

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