亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

同時多次下載同一文件

同時多次下載同一文件

Go
慕桂英4014372 2023-07-17 17:49:01
我同時從配置對象切片(其中每個配置對象包含需要下載的 URL)下載文件(使用 WaitGroup),但是當我使用并發時,我會在每次執行時獲得完全相同的數據。我相信我將下面的所有內容都包含在一個最小的可重復示例中。這是我的進口:package mainimport (    "encoding/json"    "fmt"    "io"    "io/ioutil"    "log"    "net/http"    "os"    "path"    "path/filepath"    "strconv"    "strings"    "sync")循環遍歷我的對象并執行 go 例程來下載每個文件的方法如下:func downloadAllFiles(configs []Config) {    var wg sync.WaitGroup    for i, config := range configs {        wg.Add(1)        go config.downloadFile(&wg)    }    wg.Wait()}基本上,我的功能是將文件從 URL 下載到 NFS 上存儲的目錄中。這是下載功能:func (config *Config) downloadFile(wg *sync.WaitGroup) {    resp, _ := http.Get(config.ArtifactPathOrUrl)    fmt.Println("Downloading file: " + config.ArtifactPathOrUrl)    fmt.Println(" to location: " + config.getNfsFullFileSystemPath())    defer resp.Body.Close()    nfsDirectoryPath := config.getBaseNFSFileSystemPath()    os.MkdirAll(nfsDirectoryPath, os.ModePerm)    fullFilePath := config.getNfsFullFileSystemPath()    out, err := os.Create(fullFilePath)    if err != nil {        panic(err)    }    defer out.Close()    io.Copy(out, resp.Body)    wg.Done()}這是 Config 結構的最小部分:type Config struct {    Namespace                 string                      `json:"namespace,omitempty"`    Tenant                    string                      `json:"tenant,omitempty"`    Name                      string                      `json:"name,omitempty"`    ArtifactPathOrUrl         string                      `json:"artifactPathOrUrl,omitempty"`}以下是實例/輔助函數:func (config *Config) getDefaultNfsURLBase() string {    return "http://example.domain.nfs.location.com/"}func (config *Config) getDefaultNfsFilesystemBase() string {    return "/data/nfs/location/"}func (config *Config) getBaseNFSFileSystemPath() string {    basePath := filepath.Dir(config.getNfsFullFileSystemPath())    return basePath}
查看完整描述

1 回答

?
qq_笑_17

TA貢獻1818條經驗 獲得超7個贊

我很確定你的猜測


這個問題讓我想起如果您嘗試運行帶有閉包的 for 循環并最終將單個對象實例鎖定到循環中并在同一個對象上重復執行,會發生什么。


是正確的。簡單的修復方法是“分配給本地變量”,例如


for _, config := range configs {

    wg.Add(1)

    cur := config

    go cur.downloadFile(&wg)

}

但我不喜歡將 waitgroup 作為參數的 API,所以我建議


for _, config := range configs {

    wg.Add(1)

    go func(cur Config) {

       defer wg.Done()

       cur.downloadFile()

    }(config)

}

并將downloadFile簽名更改為func (config *Config) downloadFile()并刪除wg其中的用法。


查看完整回答
反對 回復 2023-07-17
  • 1 回答
  • 0 關注
  • 179 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號