aller en boucle simultanée

1 La variable f est partagée par toutes les valeurs de fonctions anonymes et sera mise à jour par des itérations de boucle successives.
2 . Au moment où la nouvelle goroutine commence à exécuter la fonction littérale, la boucle for peut avoir mis à jour f et commencé une autre itération ou (plus probablement) a terminé la boucle entière,

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 doit être appelé avant que la goroutine de travail ne démarre, il n'y a aucun moyen d'être sûr que Add est appelé avant que la goroutine "plus proche" appelle Wait.

Fonctionnement en deux étapes : fermeture après attente,

Si l'opération en deux étapes est placée dans la goroutine principale, avant la boucle, alors elle ne se terminera jamais,
- car il n'y a pas de boucle de plage pour accepter size: = tailles de plage, done ne se terminera jamais.

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

おすすめ

転載: blog.csdn.net/qq_34751210/article/details/127773156