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

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

Go 例程返回的結果少于實際結果

Go 例程返回的結果少于實際結果

Go
jeck貓 2022-10-10 17:01:19
我有一個循環,它對給定的鍵進行哈希處理并返回結果,但是在結果上,如果我有 1500 個進入循環的 URL 列表,它永遠不會返回 1500 的結果,它總是返回小于 1500。我在下面做錯了什么:if len(URLLists) > 0 {    var base = "https://example.com/query?="    var wg sync.WaitGroup    var mutex = sync.Mutex{}    wg.Add(len(URLLists))    for _, url := range URLLists {        // wg.Add(1)  OR above for loop        go func() {            defer wg.Done()            hmac := "HMAX_123"            out := encoding.HexEncodeURL(hmac, url)            final := base + out            list := Lists{                Old: url,                New: final,            }            mutex.Lock()            response.URL = append(response.URL, list)            mutex.Unlock()        }()    }    wg.Wait()    jR, err := json.Marshal(response)    if err != nil {        w.Write([]byte(`{"success": false, "url" : ""}`))    } else {        w.Write(jR)    }    return}我嘗試了這兩種方法Add- 一個內部循環乘以 1,一個外部循環乘以總長度。我希望函數返回所有 1500 個 URL 列表,而不僅僅是“700、977、1123”隨機列表??雌饋?-wg.Wait()不是在等待所有wg.Add- 添加
查看完整描述

2 回答

?
哆啦的時光機

TA貢獻1779條經驗 獲得超6個贊

這個程序有幾個錯誤:


您正在 goroutine 中使用循環變量。循環變量在每次迭代時都會被重寫,因此當 goroutine 使用 時url,它可能已經移動到下一個 URL,因此您最終會得到多個 goroutine 散列相同的 URL。修理:

    for _, url := range URLLists {

        url:=url // Create a copy of the url

        // wg.Add(1)  OR above for loop

你有一個競爭條件。你必須保護對它的訪問,response.URL因為它是由多個 goroutine 編寫的。您可以使用互斥鎖:

lock:=sync.Mutex{}

for _,url:=...

  ...

  lock.Lock()

  response.URL = append(response.URL, list)

  lock.Unlock()

更好的方法是通過通道發送這些。


查看完整回答
反對 回復 2022-10-10
?
子衿沉夜

TA貢獻1828條經驗 獲得超3個贊

你在這里有一個非常嚴重的比賽條件:

response.URL = append(response.URL, list)

如果您要啟動多達 1500 個并發 Go 例程,那么您將有數百個都嘗試同時執行這一行。他們將不斷地覆蓋對數組的更改。

您需要使用 保護將新數據插入到此切片中sync.Mutex,或者通過通道發送結果并讓單個 Go 例程從該通道讀取并附加到列表中。


查看完整回答
反對 回復 2022-10-10
  • 2 回答
  • 0 關注
  • 143 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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