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 + "&a=0&b=1&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 }
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) } ...
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!