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

Golang并行计算带边界交互矩阵时goroutine数据污染问题求助

问题根因分析

你的代码存在两个核心问题直接导致数据污染和结果异常:

  • 并发写冲突(核心原因):
    Go语言的切片是引用类型,你对原始矩阵boards做切片得到子矩阵subBoard时,subBoard中存储的每一行切片仍然和原矩阵共享底层数组,没有生成独立的行数据副本。
    你之前的无重叠分块版本,各个子矩阵的行范围完全不重合,每个goroutine只会修改专属的行数据,因此没有触发冲突,运行结果符合预期。
    而带重叠的版本中,相邻子矩阵共享了重叠行的底层数组,多个goroutine会同时修改同一行的元素,会出现行元素被多次加固定值、读写顺序混乱的问题,直接表现就是goroutine内部拿到的子矩阵值和传入时不一致。
  • 拼接逻辑变量未初始化bug:
    你在处理子矩阵计算结果的拼接逻辑中,actualEnd变量未完成初始化就直接做减法运算:
endIdx := startIdx + len(subBoard)
var actualStart int
var actualEnd int
if startIdx == 0 {
    actualStart = startIdx
    actualEnd = actualEnd - 1 // actualEnd未赋值,默认值为0,运算后为-1,逻辑完全错误
}

正确的写法是先把endIdx赋值给actualEnd,再根据子矩阵位置做调整。

修复方案
  1. 给每个传入goroutine的子矩阵做深拷贝,避免共享底层数组:
// 以首块逻辑为例,其余分支同理
subBoard := boards[startIdx : endIdx+1]
// 新增深拷贝逻辑
copySubBoard := make([][]int, len(subBoard))
for k := range subBoard {
    copySubBoard[k] = make([]int, len(subBoard[k]))
    copy(copySubBoard[k], subBoard[k])
}
fmt.Println("The input of subBoard: ", copySubBoard, "with start idx ",startIdx)
go sumRow(copySubBoard, c, startIdx)
  1. 修复拼接逻辑的变量初始化问题:
endIdx := startIdx + len(subBoard)
actualStart := startIdx
actualEnd := endIdx
if startIdx == 0 {
    actualEnd -= 1
} else if endIdx == len(newBoard) {
    actualStart += 1
} else {
    actualStart += 1
    actualEnd -= 1
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:45:01