根据output的判断,等待组wg
的等待时间不足以下载文件。我正在通过副本将参数传递给goroutine。我正在等待带有wg
功能的Wait
:
var links = [...]string{
"https://i.4cdn.org/1587388512681.webm",
"https://i.4cdn.org/1587388577598.webm",
"https://i.4cdn.org/1587388649272.webm",
"https://i.4cdn.org/1587388711701.webm",
"https://i.4cdn.org/1587388776089.webm",
"https://i.4cdn.org/1587388844315.webm",
}
var dir = "files"
func downloadFile(
webUri, localUri string,
wg *sync.WaitGroup,
) (written int64, err error) {
fmt.Printf("Downloading %s as %s\n", webUri, localUri)
defer fmt.Println("Leaving downloadFile function")
defer wg.Done()
written = 0
err = nil
file, err := os.Create(localUri)
if err != nil {
return
}
defer file.Close()
resp, err := http.Get(webUri)
if err != nil {
return
}
if resp.StatusCode != 200 {
err = fmt.Errorf(
"Downloading %s failed, response status code: %d",
webUri,
resp.StatusCode,
)
return
}
defer resp.Body.Close()
written, err = io.Copy(file, resp.Body)
fmt.Printf("[SUCCESS] Downloading %s as %s\n", webUri, localUri)
return
}
func main() {
var wg sync.WaitGroup
for i, link := range links {
wg.Add(1)
cwd, err := os.Getwd()
if err != nil {
panic(fmt.Errorf("Cannot determine $HOME: %s", err))
}
newFileName := fmt.Sprintf(
"%s/%s/%d",
cwd,
dir,
i,
)
go downloadFile(link, newFileName, &wg)
}
wg.Wait()
}
是什么原因导致downloadFile
过早退出?
延迟功能以建立功能的相反顺序执行。问题中的代码是:
defer fmt.Println("Leaving downloadFile function")
defer wg.Done()
对wg.Done()
的调用在对fmt.Println
的调用之前执行。因此,主函数可以从wg.Wait()
返回并在调用fmt.Println
之前退出。由于在main返回时程序退出,因此可能无法执行对fmt.Println
的调用。
通过反转延迟功能的顺序解决此问题:
defer wg.Done()
defer fmt.Println("Leaving downloadFile function")