loops - 嵌套for循环中的并发

标签 loops go concurrency

我正在尝试进行一些图像分析,并分析 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 写入 channel ,然后将该 channel 的内容放入映射中。我做错了什么?

最佳答案

当所有 goroutine 完成后,您应该关闭 channel 。为此,您首先必须使用 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()
           ...

然后在所有 gorotine 完成后关闭 channel :

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

关于loops - 嵌套for循环中的并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76657895/

相关文章:

java - 向现有的 java 程序添加循环?

java - 没有索引声明的 for 循环

arrays - 将新行追加到多维 slice

go - context.WithCancel 和 context.WithTimeout API 如何一起使用,有必要吗?

struct - 如何在 Go 中从结构体创建 []string

jquery .each 仅适用于第一个元素

Java - For 循环将无法完成,仅三个循环后就会崩溃

java - 乐观锁 - Hibernate 的并发问题

java - 您可以只使用 AtomicInteger 来创建 ReadWriteLock 锁吗?

Java 8 不安全 : xxxFence() instructions