我使用go例程并行地将矩阵相乘。我的索引超出范围,但是当我运行相同的代码顺序时,它的工作原理。 (顺序我的意思是评论go line)。我正在使用延迟所以我不必等待我的例程结束,因为它将是最后一个叫做
错误 D:\ 0000>去运行Ap.go 恐慌:运行时错误:索引超出范围
goroutine 5 [running]:
main.pmultiply(0xc04206c000, 0x3, 0x3, 0xc04206c050, 0x3, 0x3, 0x1, 0x3, 0x0)
D:/0000/Ap.go:48 +0x95
main.multiply.func1(0xc04206c0a0, 0x3, 0x3, 0xc04200e090, 0xc04200e098, 0xc04206
c000, 0x3, 0x3, 0xc04206c050, 0x3, ...)
D:/0000/Ap.go:64 +0x94
created by main.multiply
D:/0000/Ap.go:63 +0x1d7
exit status 2
CODE
package main
import "fmt"
func main(){
matrix_a := make([][]int,3);
for i:=0;i<len(matrix_a);i++{
matrix_a[i]=make([]int,3);
}
for i:=0;i<len(matrix_a);i++{
for j:=0;j<len(matrix_a[0]);j++{
matrix_a[i][j] = 2;
}
}
matrix_b := make([][]int,3);
for i:=0;i<len(matrix_b);i++{
matrix_b[i]=make([]int,3);
}
for i:=0;i<len(matrix_b);i++{
for j:=0;j<len(matrix_b[0]);j++{
matrix_b[i][j] = 2;
}
}
defer fmt.Println(multiply(matrix_a,matrix_b));
}
func pmultiply(matrix_a [][] int,matrix_b [][] int,row int,col int) int{
sum := 0;
for z:=0;z<len(matrix_a[0]);z++{
sum = sum + matrix_a[row][z] * matrix_b[z][col];
}
return sum;
}
func multiply(matrix_a [][] int,matrix_b [][] int) ([][] int){
matrix_c := make([][]int,3);
for i:=0;i<len(matrix_c);i++{
matrix_c[i]=make([]int,3);
}
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
go func(){
matrix_c[i][j] = pmultiply(matrix_a,matrix_b,i,j);
}()
}
}
return matrix_c;
}
答案 0 :(得分:1)
我看到两个问题:
const urlReg = /((\w*?)((:\/\/)|www|\w\.{1}\w{2,})[^"<\s]+)(?![^<>]*>|[^"]*?<\/a)/g;
multiply
和i
在j
中存在经典的闭包问题。matrix_c
返回multiply
之前,无法保证计算for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
go func(){
matrix_c[i][j] = pmultiply(matrix_a,matrix_b,i,j);
}()
}
}
。第一个就在这里:
i
匿名函数在j
时保留对i
和j
的引用,而不是go func() { ... }()
和i
的实际值,因此当goroutine执行时,j
和i
可以是0到3之间的任何值(包含)。这就是你知道的错误来自:j
或i
是三,因为goroutine在循环完成后正在执行。最简单的解决方案是在正确的时间强制j
和go func(i, j int) {
matrix_c[i][j] = pmultiply(matrix_a, matrix_b, i, j)
}(i, j)
进行评估:
return matrix_c
第二个问题是,在你import "sync"
之前,goroutines不一定都会完成,甚至没有保证任何一个都能完成。最简单的解决方案是使用https://testask.com/item/45e20490-2b86-4b6a-8772-5ed96f64de52等待它们完成。首先你var wg sync.WaitGroup
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
wg.Add(1) // Tell the WaitGroup to wait for another thing.
go func(i, j int) {
matrix_c[i][j] = pmultiply(matrix_a, matrix_b, i, j)
wg.Done() // Tell it that we're done.
}(i, j)
}
}
,然后调整循环:
wg.Wait()
return matrix_c
然后在返回前等待:
defer
对评论的回复: defer
不起作用,sync.WaitGroup
:
“defer”语句调用一个函数,该函数的执行被推迟到周围函数返回的那一刻,因为周围的函数执行了一个return语句,到达了它的函数体的末尾,或者因为相应的goroutine是恐慌的。 / p>
就是这样,当执行离开周围的功能时,它会安排执行某些操作。 TheLabel.color = UIColor.black.withAlphaComponent(0.2)
与等待线程/ goroutine无关,也不知道延迟函数可能创建的goroutine。