英文:
go-routines and channels in go
问题
我正在尝试使用Go的并发功能并行运行一些计算:
func intensity_calc(input Matrix, distance float64) Matrix {
output := create_matrix(len(input), len(input[0]))
var wg sync.WaitGroup
reverse := len(input)
wg.Add(len(input) / 2)
for i := 0; i < len(input)/2; i++ {
output[i][x_ln] = input[i][x_ln]
go func() { // 创建一个go协程
points <- contributions_sum(input, distance, input[i][x_ln])
output[i][y_ln] = <-points
output[reverse][y_ln] = output[i][y_ln]
fmt.Println(i)
defer wg.Done() // 处理完成
}()
}
wg.Wait() // 等待所有进程完成
return output
}
output
是一个二维数组
代码假设从数组 input
中获取值,并将它们发送到一个函数,该函数将值返回到通道 points
中。
通道在全局范围内定义:
var points chan float64
在 main()
函数中:
points = make(chan float64)
但是我一直收到以下错误:
goroutine 2017 [chan send]:
main.intensity_calc.func1(0xc04206a000, 0xfa1, 0xfa1, 0x3f50624dd2f1a9fc, 0xc0420bb660, 0xc042094000, 0xfa1, 0xfa1, 0xfa1, 0xc0420bb650)
C:/.../go concurrent calculation.go:71 +0xbf
created by main.intensity_calc
C:/.../go concurrent calculation.go:76 +0x1c0
英文:
I'm trying to run a few calculations in parallel using Go's concurrency:
func intensity_calc(input Matrix, distance float64) Matrix {
output := create_matrix(len(input), len(input[0]))
var wg sync.WaitGroup
reverse := len(input)
wg.Add(len(input) / 2)
for i := 0; i < len(input)/2; i++ {
output[i][x_ln] = input[i][x_ln]
go func() { // creates a go-routine
points <- contributions_sum(input, distance, input[i][x_ln])
output[i][y_ln] = <-points
output[reverse][y_ln] = output[i][y_ln]
fmt.Println(i)
defer wg.Done() // process is done
}()
}
wg.Wait() // wait until all processes are finished
return output
}
- output is a 2D array
the code supposes to take values from the array input send them to a function that returns the values into the channel points.
the channel is defined globally:
var points chan float64
and in the main() function:
points = make(chan float64)
but I keep getting this error:
goroutine 2017 [chan send]:
main.intensity_calc.func1(0xc04206a000, 0xfa1, 0xfa1, 0x3f50624dd2f1a9fc, 0xc0420bb660, 0xc042094000, 0xfa1, 0xfa1, 0xfa1, 0xc0420bb650)
C:/.../go concurrent calculation.go:71 +0xbf
created by main.intensity_calc
C:/.../go concurrent calculation.go:76 +0x1c0
答案1
得分: 2
指令
var points = make(chan float64)
创建了一个无缓冲通道,这意味着
points <- contributions_sum(input, distance, input[i][x_ln])
将会阻塞,直到另一个Go协程从points通道中读取数据。
考虑到你发布的代码中的所有Go协程在从通道中读取数据之前都会发送数据到该通道,它们都会阻塞等待从同一个通道中读取数据,而这将永远不会发生(除非你在你没有发布的代码中进行了这样的操作,你应该发布出来)。因此,你遇到了一个死锁(通常情况下,你引用的错误信息是否是控制台显示的所有内容?)。
英文:
The instruction
var points = make(chan float64)
creates an unbuffered channel, which in turn means that
points <- contributions_sum(input, distance, input[i][x_ln])
will block until another go-routine reads from points.
Considering that all the go-routines in the code you posted perform a send on the channel before reading from it, they will all block waiting for a read on the same channel that will never happen (unless this is done in the code you didn't post, which you should have). As a result, you have a deadlock (which is usually written, is the error you quoted everything the console displays?).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论