2015-12-14 23 views
5

Io uso sync.WaitGroup, defer wg.Close() e wg.Wait() per attendere il completamento delle mie goroutine.Applicazione Golang che utilizza sync.WaitGroup e canali non esce mai

Il programma attende, ma non esce mai.

Questo è il mio programma (eseguibile):

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 
} 

caso non questa uscita programma quando sono stati scaricati tutte le citazioni? (FYI: Ho appena iniziato a imparare GO)

risposta

13

Non stai mai chiudendo il canale fetchedSymbols, in modo che il ciclo di intervallo non esca mai.

Un modo per gestirlo è utilizzare il WaitGroup che è già necessario segnalare quando chiudere il canale. L'intervallo tra fetchedSymbols è sufficiente per bloccare l'avanzamento in main e non è necessario un altro canale o WaitGroup.

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

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

... 
Problemi correlati