WaitGroups等待的时间不足以下载文件

问题描述 投票:0回答:1

根据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过早退出?

go goroutine
1个回答
0
投票

延迟功能以建立功能的相反顺序执行。问题中的代码是:

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")
© www.soinside.com 2019 - 2024. All rights reserved.