2015-12-14 24 views
5

'dan çıkıyorum. Ümitlerimin tamamlanmasını beklemek için sync.WaitGroup, defer wg.Close() vekullanıyorum.Golang app sync.WaitGroup & kanalları hiçbir zaman

Program bekler, ancak hiç çıkarmaz.

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 
} 

bu program çıkış tüm tırnak

indirilmiş olmamalı:

Bu (çalıştırılabilir) programım nedir? (FYI: Sadece öğrenmeyi başlattım)

cevap

13

fetchedSymbols kanalını asla kapatmıyorsunuz, böylece aralık döngüsü asla çıkmayacak.

Bunu işlemenin bir yolu, kanalın ne zaman kapatılacağını bildirmeniz gereken WaitGroup'u kullanmaktır. fetchedSymbols üzerinden değişiklik yapmak, ilerlemeyi engellemek için yeterlidir ve başka bir kanala veya WaitGroup'a ihtiyacınız yoktur.

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

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

...