加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-16 19:04:19 所属栏目:大数据 来源:网络整理
导读:我使用sync.WaitGroup,延迟wg.Close()和wg.Wait()来等待我的goroutines完成. 该程序确实等待,但它永远不会退出. 这是我的程序(runnable): package mainimport ( "fmt" "io" "log" "net/http" "os" "sync")var symbols = []string{ "ASSA-B.ST","ELUX-B.ST",
我使用sync.WaitGroup,延迟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)

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

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

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

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

...

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读