go 并发循环

1 变量f是被所有的匿名函数值所共享,且会被连续的循环迭代所更新的。
2 。当新的goroutine开始执行字面函数时,for循环可能已经更新了f并且开始了另一轮的迭代或者(更有可能的)已经结束了整个循环,

func makeThumbnails6(filenames <-chan string) int64 {
    
    
    sizes := make(chan int64)
    var wg sync.WaitGroup // number of working goroutines
    for f := range filenames {
    
    
        wg.Add(1)
        // worker
        go func(f string) {
    
    
            defer wg.Done()
            thumb, err := thumbnail.ImageFile(f)
            if err != nil {
    
    
                log.Println(err)
                return
            }
            info, _ := os.Stat(thumb) // OK to ignore error
            sizes <- info.Size()
        }(f)
    }

    // closer
    go func() {
    
    
        wg.Wait()
        close(sizes)
    }()

    var total int64
    for size := range sizes {
    
    
        total += size
    }
    return total
}

Add必须在worker goroutine开始之前调用 ,我们没办法确定Add是在"closer" goroutine调用Wait之前被调用。

两步操作:wait 后 close,

如果两步操作被放在了main goroutine中,在循环之前,这样的话就永远都不会结束了,
–因为没有range loop 去接受 size:= range sizes 的话 ,done 永远结束不了。

如果在循环之后,那么又变成了不可达的部分,因为没有任何东西去关闭这个channel,这个循环就永远都不会终止。
 (当channel没有 数据 总会阻塞这个channel)

猜你喜欢

转载自blog.csdn.net/qq_34751210/article/details/127773156