go-routines and channels in go

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

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 &lt; len(input)/2; i++ {
	    output[i][x_ln] = input[i][x_ln]
	    go func() { // creates a go-routine
		points &lt;- contributions_sum(input, distance, input[i][x_ln])
		output[i][y_ln] = &lt;-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 &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:

确定