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
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 个线程在这里并不总是足够的。)
- 2 回答
- 0 关注
- 169 浏览
添加回答
举报