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

Go语言如何并发对切片所有元素执行计算密集型操作?

Go并发处理切片元素的正确实现方案

问题背景

现有切片:

problemArray := []int{77,44,34,752,12}

需对切片中每个元素执行支持并发的计算密集型操作,操作函数定义如下:

func ComputeHeavyOperation(num int) int {
     time.Sleep(time.Second * 2)
     return num * 2
}

期望通过SomeNewFunc(problemArray, ComputeHeavyOperation)获取结果,预期输出为[154, 88, 68, 1504, 24](注:原预期中的144为笔误,77*2实际应为154)。

你原有代码的问题分析

你尝试的代码存在两个核心问题:

  1. 循环变量捕获错误:goroutine中直接引用循环变量n,由于goroutine执行时机滞后,所有goroutine最终捕获的都是循环结束后的n值(即切片最后一个元素5),因此输出全为10。
  2. 通道关闭时机错误:mathematicalCompute启动goroutine后立刻执行defer close(c),此时goroutine还未开始发送数据,主goroutine遍历通道时直接结束,导致仅输出Hello World;注释掉close后,所有goroutine发送完数据后,主goroutine仍在等待通道数据,触发死锁。

正确实现方案

保持原顺序的实现(推荐)

该方案通过sync.WaitGroup等待所有goroutine完成,同时保证结果顺序与原切片一致:

package main

import (
	"fmt"
	"sync"
	"time"
)

func ComputeHeavyOperation(num int) int {
	time.Sleep(time.Second * 2)
	return num * 2
}

func SomeNewFunc(arr []int, op func(int) int) []int {
	result := make([]int, len(arr))
	var wg sync.WaitGroup

	for i, n := range arr {
		wg.Add(1)
		// 将当前索引和元素值作为参数传入goroutine,避免循环变量捕获问题
		go func(idx int, num int) {
			defer wg.Done()
			result[idx] = op(num)
		}(i, n)
	}

	// 等待所有goroutine执行完毕
	wg.Wait()
	return result
}

func main() {
	problemArray := []int{77, 44, 34, 752, 12}
	output := SomeNewFunc(problemArray, ComputeHeavyOperation)
	fmt.Println(output) // 输出: [154 88 68 1504 24]
}

流式通道实现(结果顺序随机)

如果不需要保持原顺序,可通过通道流式接收结果:

func SomeNewFuncWithChan(arr []int, op func(int) int) []int {
	result := make([]int, 0, len(arr))
	c := make(chan int, len(arr))
	var wg sync.WaitGroup

	for _, n := range arr {
		wg.Add(1)
		go func(num int) {
			defer wg.Done()
			c <- op(num)
		}(n)
	}

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

	// 遍历通道收集结果
	for val := range c {
		result = append(result, val)
	}

	return result
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:08:10