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

使用Go Goroutine并行计算数组最大值遇死锁,求技术指导

问题分析与修复

死锁原因

原代码的核心问题在于主循环中每次迭代两次读取channel:

  • 10个goroutine总共向channel发送10个值
  • 主循环执行10次,每次if max < <-ch读取一次,max = <-ch又读取一次,总共需要读取20个值
  • 当10个值被读完后,主goroutine会阻塞在channel读取操作上,没有其他goroutine发送数据,最终触发死锁

基础修复(解决死锁)

先修正读取逻辑,每次迭代只读取一次channel值:

package main

import (
    "fmt"
    "math"
)

func main() {
    arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    max := math.MinInt32
    ch := make(chan int)

    for i := 0; i < len(arr); i++ {
        go func(i int) {
            ch <- arr[i]
        }(i)
    }

    // 修正:每次迭代只读取一次channel值
    for i := 0; i < len(arr); i++ {
        val := <-ch
        if max < val {
            max = val
        }
    }
    fmt.Println(max)
}

结合Wait Group的优化方案(符合需求)

按照你要求的使用WaitGroup管理goroutine,同时更优雅地处理channel关闭,避免依赖数组长度控制循环次数:

package main

import (
    "fmt"
    "math"
    "sync"
)

func main() {
    arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    max := math.MinInt32
    ch := make(chan int)
    var wg sync.WaitGroup

    wg.Add(len(arr))
    for i := 0; i < len(arr); i++ {
        go func(i int) {
            defer wg.Done()
            ch <- arr[i]
        }(i)
    }

    // 单独启动goroutine,等待所有任务完成后关闭channel
    go func() {
        wg.Wait()
        close(ch)
    }()

    // 遍历channel直到关闭,计算最大值
    for val := range ch {
        if val > max {
            max = val
        }
    }

    fmt.Println(max)
}

关键说明

  • WaitGroup用于等待所有goroutine完成数据发送任务
  • 单独goroutine在WaitGroup等待完成后关闭channel,主goroutine的range循环会在channel关闭后自动退出
  • 避免硬编码循环次数,代码更健壮,适配数组长度变化的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:00:26