为了账号安全,请及时绑定邮箱和手机立即绑定

使用 sync.WaitGroup 和频道的 Golang 应用程序永远不会退出

使用 sync.WaitGroup 和频道的 Golang 应用程序永远不会退出

Go
狐的传说 2021-11-29 16:15:04
我使用sync.WaitGroup,defer wg.Close()并wg.Wait()等待我的 goroutine 完成。该程序确实等待,但它永远不会退出。这是我的程序(可运行):package mainimport (    "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}下载完所有报价后,该程序不应该退出吗?(仅供参考:我刚开始学习围棋)
查看完整描述

1 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

您永远不会关闭fetchedSymbols通道,因此范围循环永远不会退出。


处理此问题的一种方法是使用您已经必须发出信号的 WaitGroup 何时关闭通道。测距在fetchedSymbols足以阻止主要的进步,你并不需要另一个通道或WaitGroup。


...

go func() {

    wg.Wait()

    close(fetchedSymbols)

}()


for response := range fetchedSymbols {

    fmt.Println("fetched " + response)

}


...


查看完整回答
反对 回复 2021-11-29
  • 1 回答
  • 0 关注
  • 115 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信