Maison > développement back-end > Golang > Pourquoi une combinaison de « sync.WaitGroup » et de canaux entraîne-t-elle un blocage dans Go ?

Pourquoi une combinaison de « sync.WaitGroup » et de canaux entraîne-t-elle un blocage dans Go ?

Susan Sarandon
Libérer: 2024-10-30 17:43:02
original
996 Les gens l'ont consulté

Why Does a `sync.WaitGroup` and Channel Combination Lead to a Deadlock in Go?

Comprendre les blocages lors de l'utilisation de sync.WaitGroup et des canaux dans Go

Les développeurs rencontrent souvent des problèmes avec leurs applications Go qui ne se ferment jamais lorsqu'ils utilisent sync.WaitGroup et les chaînes. Cet article explore les raisons de ces blocages et propose une solution à l'aide du WaitGroup.

Considérez l'exemple de code fourni :

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"
    "sync"
)

var symbols = []string{
    "ASSA-B.ST",
    "ELUX-B.ST",
    "HM-B.ST",
}

func main() {

    fmt.Println("fetching quotes...")

    fetchedSymbols := make(chan string)
    var wg sync.WaitGroup
    wg.Add(len(symbols))

    for _, symbol := range symbols {
        go fetchSymbol(symbol, &wg, fetchedSymbols)
    }

    for response := range fetchedSymbols {
        fmt.Println("fetched " + response)
    }

    wg.Wait()

    fmt.Println("done")

}

func fetchSymbol(symbol string, wg *sync.WaitGroup, c chan<- string) {
    defer wg.Done()
    resp, err := http.Get("http://ichart.yahoo.com/table.csv?s=" + symbol + "&amp;a=0&amp;b=1&amp;c=2000")
    defer resp.Body.Close()

    if err != nil {
        log.Fatal(err)
    }

    out, err := os.Create("./stock-quotes/" + symbol + ".csv")
    defer out.Close()

    if err != nil {
        log.Fatal(err)
    }

    io.Copy(out, resp.Body)
    c <- symbol
}
Copier après la connexion

Dans ce code, la boucle de plage sur les symboles récupérés bloquera le principal fonctionner indéfiniment. Pourquoi? Parce que le canal fetchedSymbols n’est jamais fermé. Pour résoudre cette impasse, le WaitGroup peut être utilisé pour signaler quand fermer le canal :

...
go func() {
    wg.Wait()
    close(fetchedSymbols)
}()

for response := range fetchedSymbols {
    fmt.Println("fetched " + response)
}

...
Copier après la connexion

Comme le WaitGroup suit déjà lorsque toutes les goroutines sont terminées, il peut être exploité pour déclencher la fermeture du canal fetchedSymbols. , garantissant que la boucle de plage se termine correctement.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal