2 回答

TA貢獻1805條經驗 獲得超9個贊
你實際上沒有WaitGroup正確使用。每次你調用wg.Done()它實際上是從前一個中減去 1wg.Add以確定給定的任務已完成。最后,您需要wg.Wait()同步等待所有任務。WaitGroups通常用于并行運行多個任務的扇出使用。
根據您的代碼示例,最簡單的方法是將 傳入wg您的任務,然后在任務內部uploadT調用。wg.Done()請注意,您還需要使用指針而不是結構值。
下一個實現細節是在循環外調用wg.Wait(),因為你想阻塞直到所有任務都完成,因為你的所有任務都在運行,go這使得它異步。如果你不這樣做wg.Wait(),它會像你說的那樣立即記錄jobID。讓我知道是否清楚。
作為樣板,它應該看起來像這樣
func task(wg *sync.WaitGroup) {
wg.Done()
}
wg := &sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go task(wg)
}
wg.Wait()
// do something after the task is done
fmt.Println("done")
我要注意的另一件事是,在您當前的代碼示例中,您正在使用通道,但您沒有對推送到通道中的值做任何事情,因此您可以從技術上刪除它們。

TA貢獻1780條經驗 獲得超5個贊
你的代碼有點混亂。但是,如果我理解正確你正在嘗試做什么,你正在處理一個請求列表,并希望返回每個請求的 url 和狀態以及每個請求完成的時間。并且您想并行處理這些。
您根本不需要使用 WaitGroups。當您只想運行一堆任務而不關心結果,只想知道一切何時完成時,WaitGroups 非常有用。但如果你要返回結果,渠道就足夠了。
這是一個示例代碼,可以執行我認為您正在嘗試執行的操作
package main
import (
"time"
"fmt"
)
type Result struct {
URL string
Status string
Finished string
}
func task(url string, c chan string, d chan string) {
time.Sleep(time.Second)
c <- url
d <- "Success"
}
func main() {
var results []Result
urls := []string{"url1", "url2", "url3", "url4", "url5"}
c := make(chan string, len(urls))
d := make(chan string, len(urls))
for _, u := range urls {
go task(u, c, d)
}
for i := 0; i < len(urls); i++ {
res := Result{}
res.URL = <-c
res.Status = <-d
res.Finished = time.Now().UTC().Format(time.RFC3339)
results = append(results, res)
}
fmt.Println(results)
}
你可以在操場上試試https://play.golang.org/p/N3oeA7MyZ8L
也就是說,這有點脆弱。您正在制作與網址列表大小相同的頻道。這對于一些 url 來說效果很好,但是如果你有一個包含一百萬個 url 的列表,你將創建一個相當大的頻道。您可能希望將通道緩沖區大小固定為某個合理的值,并在發送請求之前檢查通道是否已準備好進行處理。這樣你就可以避免一次發出一百萬個請求。
- 2 回答
- 0 關注
- 132 瀏覽
添加回答
舉報