You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测量Go并发process函数执行时间?错误排查与修正

问题分析与修正方案

核心错误点

  • 循环变量引用问题
    Go的for循环里,photo是复用的同一个变量,所有goroutine都会指向这个变量的内存地址。如果goroutine启动后没立刻执行,循环已经迭代了好几轮,此时photo的值已经变成后续甚至最后一个元素,导致多个goroutine处理同一个photo,计时自然对应不上正确的任务,结果失真。

  • 程序提前终止风险
    最后那段go func() { wg.Wait() }()完全多余,主goroutine不会等这个匿名goroutine,会直接继续执行(如果后面没别的代码就直接退出),导致所有正在跑的worker goroutine被强制结束,计时结果会被截断,显示的时间远短于实际耗时。

  • 输出格式错误
    fmt.Println("took %s", time.Since(start))不会解析占位符,会直接把两个参数都输出,结果会是took %s 1.2s这种错误格式,根本看不到正确的计时展示。

修正后的代码

var wg sync.WaitGroup
for _, photo := range photos {
    // 复制当前迭代的photo值,每个goroutine持有独立副本
    currentPhoto := photo
    wg.Add(1)
    
    go func() {
        defer wg.Done()
        start := time.Now()
        
        result := process(currentPhoto)
        
        // 用Printf正确格式化输出耗时
        fmt.Printf("处理完成,耗时: %s\n", time.Since(start))
    }()
}

// 主goroutine直接等待所有任务完成,避免程序提前退出
wg.Wait()

修正说明

  1. 复制循环变量:在循环体内新增currentPhoto := photo,创建当前迭代元素的副本,确保每个goroutine处理的都是本轮循环的正确元素,计时也能对应到真实任务。
  2. 移除多余的Wait goroutine:直接在主goroutine调用wg.Wait(),保证所有worker goroutine都执行完毕后,程序才会退出,不会出现任务被中途打断的情况。
  3. 修正输出方式:改用fmt.Printf解析占位符,正确输出格式化的耗时信息。

内容的提问来源于stack exchange,提问作者neo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 12:58:01