2015-12-14 24 views
5

Tôi sử dụng sync.WaitGroup, defer wg.Close()wg.Wait() để đợi cho các goroutin của tôi hoàn tất.Ứng dụng Golang sử dụng sync.WaitGroup & kênh không bao giờ thoát

Chương trình chờ, nhưng chương trình không bao giờ thoát.

Đây là chương trình của tôi (Runnable):

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 
} 

nên không thoát khỏi chương trình này khi tất cả các báo giá đã được tải về? (FYI: Tôi vừa mới bắt đầu học GO)

Trả lời

13

Bạn sẽ không bao giờ đóng kênh fetchedSymbols, do đó vòng lặp phạm vi sẽ không bao giờ thoát.

Một cách để xử lý việc này là sử dụng WaitGroup mà bạn đã báo hiệu khi đóng kênh. Khác nhau, trên fetchedSymbols là đủ để ngăn chặn sự tiến bộ trong chính, và bạn không cần một kênh hoặc WaitGroup.

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

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

... 
Các vấn đề liên quan