当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《使用sync.WaitGroup和频道的Golangapp永远不会退出》经验,为你挑选了1个好方法。

我用sync.WaitGroup,defer wg.Close()wg.Wait()等待我的goroutines完成.

该程序确实等待,但它永远不会退出.

这是我的程序(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
}

所有报价下载后,该程序是否应退出?(仅供参考:我刚开始学习GO)



1> JimB..:

你永远不会关闭fetchedSymbols频道,所以范围循环永远不会退出.

处理此问题的一种方法是使用已有的WaitGroup来指示何时关闭通道.范围fetchedSymbols足以阻止main中的进度,并且您不需要其他通道或WaitGroup.

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

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

...

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有