我有一個循環,它對給定的鍵進行哈希處理并返回結果,但是在結果上,如果我有 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()
更好的方法是通過通道發送這些。

子衿沉夜
TA貢獻1828條經驗 獲得超3個贊
你在這里有一個非常嚴重的比賽條件:
response.URL = append(response.URL, list)
如果您要啟動多達 1500 個并發 Go 例程,那么您將有數百個都嘗試同時執行這一行。他們將不斷地覆蓋對數組的更改。
您需要使用 保護將新數據插入到此切片中sync.Mutex
,或者通過通道發送結果并讓單個 Go 例程從該通道讀取并附加到列表中。
- 2 回答
- 0 關注
- 143 瀏覽
添加回答
舉報
0/150
提交
取消