嵌套的for循环中的并发性

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

Concurrency in nested for loop

问题

我正在尝试进行一些图像分析,并在每个 Goroutine 中分析每个像素。我的代码目前如下所示:

func FindEdgesV2(img image.Image) PointSet {
	res := make(PointSet)
	c := make(chan Point)
	bounds := img.Bounds()
	width, height := bounds.Max.X, bounds.Max.Y

	size := width*height - width*2 - height*2 + 4
	px := 0
	bar := CreateBar(size, "reading pixels...")
	for y := 1; y < height-1; y++ {
		for x := 1; x < width-1; x++ {

			go func(x, y int, c chan Point) {
				gradient := [3][3]int{}
				for i := 0; i < 3; i++ {
					for j := 0; j < 3; j++ {
						gradient[i][j] = int(Luminance(img.At(x-1+i, y-1+i)))
					}
				}

				gx, gy := 0, 0
				for i := 0; i < 3; i++ {
					for j := 0; j < 3; j++ {
						gx += gradient[i][j] * horizontal[i][j]
						gy += gradient[i][j] * vertical[i][j]
					}
				}
				colorCode := int(math.Sqrt(float64(gx*gx + gy*gy)))
				if colorCode > 80 {
					c <- Point{x, y}
				}
			}(x, y, c)

			px++
			bar.Set(px)
		}
	}
	for p := range c {
		res[p] = true
	}
	return res
}

然而,我一直遇到这个错误:

fatal error: all goroutines are asleep - deadlock!

我只是尝试使用多个 Goroutine 向通道写入数据,然后将该通道的内容放入一个映射中。我做错了什么?

英文:

I'm trying to do some image analysis, and am analyzing each pixel in a Goroutine. My code currently looks like this:

func FindEdgesV2(img image.Image) PointSet {
	res := make(PointSet)
	c := make(chan Point)
	bounds := img.Bounds()
	width, height := bounds.Max.X, bounds.Max.Y

	size := width*height - width*2 - height*2 + 4
	px := 0
	bar := CreateBar(size, &quot;reading pixels...&quot;)
	for y := 1; y &lt; height-1; y++ {
		for x := 1; x &lt; width-1; x++ {

			go func(x, y int, c chan Point) {
				gradient := [3][3]int{}
				for i := 0; i &lt; 3; i++ {
					for j := 0; j &lt; 3; j++ {
						gradient[i][j] = int(Luminance(img.At(x-1+i, y-1+i)))
					}
				}

				gx, gy := 0, 0
				for i := 0; i &lt; 3; i++ {
					for j := 0; j &lt; 3; j++ {
						gx += gradient[i][j] * horizontal[i][j]
						gy += gradient[i][j] * vertical[i][j]
					}
				}
				colorCode := int(math.Sqrt(float64(gx*gx + gy*gy)))
				if colorCode &gt; 80 {
					c &lt;- Point{x, y}
				}
			}(x, y, c)

			px++
			bar.Set(px)
		}
	}
	for p := range c {
		res[p] = true
	}
	return res
}

However, I keep getting this error:

fatal error: all goroutines are asleep - deadlock!

I'm simply trying to write to a channel using multiple Goroutines, and then put the contents of that channel into a map. What am I doing wrong?

答案1

得分: 2

当所有的goroutine都完成时,你应该关闭通道。为了做到这一点,你首先需要使用WaitGroup来检测所有的goroutine是否都完成:

...
bar := CreateBar(size, "reading pixels...")
wg := sync.WaitGroup{}
for y := 1; y < height-1; y++ {
   for x := 1; x < width-1; x++ {
        wg.Add(1)
        go func(x, y int, c chan Point) {
           defer wg.Done()
           ...

然后在所有的goroutine都完成时关闭通道:

go func() {
    wg.Wait()
    close(c)
}()
for p := range c {
    res[p] = true
}
英文:

You should close the channel when all goroutines are done. To do that, you first have to detect when all goroutines are done using a WaitGroup:

...
bar := CreateBar(size, &quot;reading pixels...&quot;)
wg:=sync.WaitGroup{}
for y := 1; y &lt; height-1; y++ {
for x := 1; x &lt; width-1; x++ {
wg.Add(1)
go func(x, y int, c chan Point) {
defer wg.Done()
...

Then close the channel when all gorotines are done:

go func() {
wg.Wait()
close(c)
}()
for p := range c {
res

= true } </details>

huangapple
  • 本文由 发表于 2023年7月11日 07:30:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76657895.html
匿名

发表评论

匿名网友

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

确定