2 回答

TA貢獻1816條經驗 獲得超6個贊
根據文檔 -
等待組等待一組大流子體完成。主戈魯丁調用 Add 以設置要等待的戈魯廷數。然后,每個戈魯丁都會運行并在完成后調用“完成”。同時,等待可用于阻止,直到所有戈魯丁都完成。
所以必須由一個戈魯廷來調用,它正在引發其他的戈魯廷,在你的情況下是戈魯廷。Add()main
在第一個代碼片段中,您正在調用其他戈魯廷內部,而不是導致問題的主要戈魯廷 -Add()
expected := 10
var wg sync.WaitGroup
for i := 0; i < expected; i++ {
go func(wg *sync.WaitGroup) {
wg.Add(1) // Do not call Add() here
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
第二個片段正在工作,因為你正在調用戈魯廷 -Add()main
expected := 10
var wg sync.WaitGroup
wg.Add(expected) // Okay
for i := 0; i < expected; i++ {
go func(wg *sync.WaitGroup) {
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
正在添加工作組。添加(預期)解決此問題的正確方法?
您也可以在 for 循環中調用 -wg.Add(1)
expected := 10
var wg sync.WaitGroup
for i := 0; i < expected; i++ {
wg.Add(1) // Okay
go func(wg *sync.WaitGroup) {
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()

TA貢獻1942條經驗 獲得超3個贊
你的第一種方法恐慌 coz (WaitGroup.Add):
“添加”將增量(可能為負數)添加到“等待組”計數器。如果計數器變為零,則釋放在 Wait 上阻止的所有大猩猩。如果計數器變為負數,則添加恐慌。
...
...
通常,這意味著對 Add 的調用應在創建 goroutine 或其他要等待的事件的語句之前執行
當在代碼末尾調用 Wait() 時,可能沒有一個 goroutine 開始執行 - 因此 WaitGroup 中保存的值為 0。然后,當您的 go 例程執行時,調用 go 例程已經發布。這將導致意想不到的行為,在您的案例中引起恐慌。也許你在那里使用了調用 go 例程中的值。
你的第二種方法絕對沒問題。您也可以在環路內調用 - 但在塊外.Add(1)
go func
- 2 回答
- 0 關注
- 90 瀏覽
添加回答
舉報