go-routines and channels in go

huangapple go评论193阅读模式
英文:

go-routines and channels in go

问题

我正在尝试使用Go的并发功能并行运行一些计算:

  1. func intensity_calc(input Matrix, distance float64) Matrix {
  2. output := create_matrix(len(input), len(input[0]))
  3. var wg sync.WaitGroup
  4. reverse := len(input)
  5. wg.Add(len(input) / 2)
  6. for i := 0; i < len(input)/2; i++ {
  7. output[i][x_ln] = input[i][x_ln]
  8. go func() { // 创建一个go协程
  9. points <- contributions_sum(input, distance, input[i][x_ln])
  10. output[i][y_ln] = <-points
  11. output[reverse][y_ln] = output[i][y_ln]
  12. fmt.Println(i)
  13. defer wg.Done() // 处理完成
  14. }()
  15. }
  16. wg.Wait() // 等待所有进程完成
  17. return output
  18. }
  • output 是一个二维数组

代码假设从数组 input 中获取值,并将它们发送到一个函数,该函数将值返回到通道 points 中。
通道在全局范围内定义:

  1. var points chan float64

main() 函数中:

  1. points = make(chan float64)

但是我一直收到以下错误:

  1. goroutine 2017 [chan send]:
  2. main.intensity_calc.func1(0xc04206a000, 0xfa1, 0xfa1, 0x3f50624dd2f1a9fc, 0xc0420bb660, 0xc042094000, 0xfa1, 0xfa1, 0xfa1, 0xc0420bb650)
  3. C:/.../go concurrent calculation.go:71 +0xbf
  4. created by main.intensity_calc
  5. C:/.../go concurrent calculation.go:76 +0x1c0
英文:

I'm trying to run a few calculations in parallel using Go's concurrency:

  1. func intensity_calc(input Matrix, distance float64) Matrix {
  2. output := create_matrix(len(input), len(input[0]))
  3. var wg sync.WaitGroup
  4. reverse := len(input)
  5. wg.Add(len(input) / 2)
  6. for i := 0; i &lt; len(input)/2; i++ {
  7. output[i][x_ln] = input[i][x_ln]
  8. go func() { // creates a go-routine
  9. points &lt;- contributions_sum(input, distance, input[i][x_ln])
  10. output[i][y_ln] = &lt;-points
  11. output[reverse][y_ln] = output[i][y_ln]
  12. fmt.Println(i)
  13. defer wg.Done() // process is done
  14. }()
  15. }
  16. wg.Wait() // wait until all processes are finished
  17. return output
  18. }
  • 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:

  1. var points chan float64

and in the main() function:

  1. points = make(chan float64)

but I keep getting this error:

  1. goroutine 2017 [chan send]:
  2. main.intensity_calc.func1(0xc04206a000, 0xfa1, 0xfa1, 0x3f50624dd2f1a9fc, 0xc0420bb660, 0xc042094000, 0xfa1, 0xfa1, 0xfa1, 0xc0420bb650)
  3. C:/.../go concurrent calculation.go:71 +0xbf
  4. created by main.intensity_calc
  5. C:/.../go concurrent calculation.go:76 +0x1c0

答案1

得分: 2

指令

  1. var points = make(chan float64)

创建了一个无缓冲通道,这意味着

  1. points <- contributions_sum(input, distance, input[i][x_ln])

将会阻塞,直到另一个Go协程从points通道中读取数据。

考虑到你发布的代码中的所有Go协程在从通道中读取数据之前都会发送数据到该通道,它们都会阻塞等待从同一个通道中读取数据,而这将永远不会发生(除非你在你没有发布的代码中进行了这样的操作,你应该发布出来)。因此,你遇到了一个死锁(通常情况下,你引用的错误信息是否是控制台显示的所有内容?)。

英文:

The instruction

  1. var points = make(chan float64)

creates an unbuffered channel, which in turn means that

  1. points &lt;- 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?).

huangapple
  • 本文由 发表于 2017年7月15日 16:37:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/45116232.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定