我有下面的代碼,獲取URL的列表,然後有條件地下載文件並將其保存到文件系統。這些文件被同時提取,並且主goroutine等待所有文件被提取。但是,在完成所有請求後,程序從不退出(並且沒有錯誤)。golang sync.waitgroup永遠不會完成
我認爲正在發生的是,不知何故在WaitGroup
走套路的量或者通過太多的增加,開始與(通過Add
)或不足夠的遞減(一Done
呼叫沒有發生)。
有什麼我明顯做錯了嗎?我將如何檢查WaitGroup
中目前有多少個例程,以便我可以更好地調試發生了什麼?
package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"strings"
"sync"
)
func main() {
links := parseLinks()
var wg sync.WaitGroup
for _, url := range links {
if isExcelDocument(url) {
wg.Add(1)
go downloadFromURL(url, wg)
} else {
fmt.Printf("Skipping: %v \n", url)
}
}
wg.Wait()
}
func downloadFromURL(url string, wg sync.WaitGroup) error {
tokens := strings.Split(url, "/")
fileName := tokens[len(tokens)-1]
fmt.Printf("Downloading %v to %v \n", url, fileName)
content, err := os.Create("temp_docs/" + fileName)
if err != nil {
fmt.Printf("Error while creating %v because of %v", fileName, err)
return err
}
resp, err := http.Get(url)
if err != nil {
fmt.Printf("Could not fetch %v because %v", url, err)
return err
}
defer resp.Body.Close()
_, err = io.Copy(content, resp.Body)
if err != nil {
fmt.Printf("Error while saving %v from %v", fileName, url)
return err
}
fmt.Printf("Download complete for %v \n", fileName)
defer wg.Done()
return nil
}
func isExcelDocument(url string) bool {
return strings.HasSuffix(url, ".xlsx") || strings.HasSuffix(url, ".xls")
}
func parseLinks() []string {
linksData, err := ioutil.ReadFile("links.txt")
if err != nil {
fmt.Printf("Trouble reading file: %v", err)
}
links := strings.Split(string(linksData), ", ")
return links
}
你推遲'wg.Done()',但你仍然有它在函數的末尾。在它有機會從錯誤中返回之前,嘗試將它移到開頭。 –
將一個指向'wg'的指針傳遞給該函數,而不是結構本身。 – plusmid