[英]Golang app using sync.WaitGroup & channels never exits
I use sync.WaitGroup
, defer wg.Close()
and wg.Wait()
to wait for my goroutines to complete. 我使用sync.WaitGroup
, defer wg.Close()
和wg.Wait()
来等待我的goroutine完成。
The program do wait, but it never exits. 该程序确实会等待,但是它永远不会退出。
This is my program (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
}
Shouldn't this program exit when all the quotes have been downloaded? 下载所有报价后,该程序是否应该退出? (FYI: I just started learning GO) (仅供参考:我刚刚开始学习GO)
You're never closing the fetchedSymbols
channel, so that range loop will never exit. 您永远不会关闭fetchedSymbols
通道,因此范围循环将永远不会退出。
One way to handle this is to use use the WaitGroup you already have to signal when to close the channel. 解决此问题的一种方法是使用WaitGroup,您已经必须在关闭通道时发出信号。 Ranging over fetchedSymbols
is enough to block the progress in main, and you don't need another channel or WaitGroup. 覆盖fetchedSymbols
足以阻止main的进度,并且您不需要其他通道或WaitGroup。
...
go func() {
wg.Wait()
close(fetchedSymbols)
}()
for response := range fetchedSymbols {
fmt.Println("fetched " + response)
}
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.