我有兴趣在 Go 中并行计算相关性。我遇到的主要问题是所有 Go 进程似乎都执行完全相同的计算。我在这里用一个非常简单的例子重现了这个问题。 我得到:
4 + 50 = 54
4 + 50 = 54
4 + 50 = 54
而不是:
1 + 20 = 21
2 + 30 = 32
3 + 40 = 43
如果我向上移动“wg.Wait()”,我会获得良好的结果,但没有并行性:( 预先感谢您的评论!
package main
import (
"fmt"
"runtime"
"sync"
)
func process_array(x, y int) int {
r := x + y
return r
}
func main() {
a1 := []int{0, 1, 2, 3, 4}
a2 := []int{10, 20, 30, 40, 50}
runtime.GOMAXPROCS(8)
var wg sync.WaitGroup
for i := 1; i < 4 ; i++ {
wg.Add(1)
go func() {
defer wg.Done()
x :=process_array(a1[i],a2[i])
fmt.Println(a1[i],"+", a2[i],"=", x)
}()
//wg.Wait() give the good result
//but it is not parallel processing
// 1 + 20 = 21
// 2 + 30 = 32
// 3 + 40 = 43
}
wg.Wait() // give a repetition of the same result :
// 4 + 50 = 54
// 4 + 50 = 54
// 4 + 50 = 54
}
最佳答案
您正在所有 goroutine 中访问 i
的相同副本。您看到的输出是因为循环恰好在任何 goroutine 开始执行之前完成。
这意味着 i
在所有 goroutine 中具有相同的值,即它在循环中具有的最后一个值。
将 i
作为参数传递给每个 goroutine,从而对每个 goroutine 的副本进行操作,解决了这个问题。
当您在循环中添加 wg.Wait()
时,您看到预期结果的原因是您随后引入了同步,等待 goroutine 完成后再开始下一个 goroutine。这意味着执行实际上是串行的,而不是并行的。
这是更新后的代码,其工作原理如下:
package main
import (
"fmt"
"runtime"
"sync"
)
func process_array(x, y int) int {
r := x + y
return r
}
func main() {
a1 := []int{0, 1, 2, 3, 4}
a2 := []int{10, 20, 30, 40, 50}
runtime.GOMAXPROCS(8)
var wg sync.WaitGroup
for i := 1; i < 4; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
x := process_array(a1[i], a2[i])
fmt.Println(a1[i], "+", a2[i], "=", x)
}(i)
//wg.Wait() give the good result
//but it is not parallel processing
// 1 + 20 = 21
// 2 + 30 = 32
// 3 + 40 = 43
}
wg.Wait() // give a repetition of the same result :
// 4 + 50 = 54
// 4 + 50 = 54
// 4 + 50 = 54
}
关于arrays - 在 Go 中并行处理数组会产生意想不到的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36092665/