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,再根据子矩阵位置做调整。
修复方案
- 给每个传入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)
- 修复拼接逻辑的变量初始化问题:
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
相关产品推荐
相关产品推荐

