2 回答

TA貢獻1946條經驗 獲得超3個贊
文檔指出,“如果重用 a 來等待多組獨立的事件,則必須在所有以前的 Wait 調用返回后進行新的 Add 調用”WaitGroup
在呼叫其他 goroutine 之前,您正在呼叫某些 goroutine,這是不允許的,如文檔所述。在你開始所有這些戈魯廷之前,你需要打電話,你還不如叫一次,wg.Done()wg.Add(1)wg.Addwg.Add(1000)
你的其他代碼工作的原因是它從不調用,你有wg.Done()
if true {
return nil
}
defer wg.Done()
因此,您始終返回而不到達 defer 語句,因此永遠不會對 進行任何調用。wg.Done()
請執行下列操作:
func callWorker(i int){
fmt.Println("Main: Starting worker", i)
// you cannot call Add here because Done has been called in other goroutines
go worker(&wg, i)
wg.Wait()
}
func main() {
wg.Add(1000) // <---- You must call Add before Done is called in any goroutine
for i := 0; i < 1000; i++ {
go callWorker(i)
}
time.Sleep(time.Second * 60)
fmt.Println("Main: Completed")
}

TA貢獻1802條經驗 獲得超5個贊
問題是,如果在等待組上調用,則不允許重用此等待組并再次調用它,直到返回調用(請參閱文檔)。在此程序中,調用工作函數本身就是一個 go 例程,所有調用工作函數都同時運行。在沒有等待對方的情況下,他們試圖在上一個電話未完成時打電話。Wait()Add()Wait()Add()Wait()
第一個工作線程生成結果時沒有錯誤,因為他們的調用在下一個調用(一個經典的競爭條件)之前幸運地返回。Wait()Add()
如果您希望工作線程同時運行,則必須移動并退出調用工作器函數。 必須在 for 循環之后調用。并且應該在調用工作之前在循環內調用,否則程序將在callWorker有機會向等待組添加某些內容之前完成,因此無需等待。不需要時間。睡在里面,太。Wait()Add()Wait()Add()Wait()main()
func main() {
for i := 0; i < 1000; i++ {
wg.Add(1)
go callWorker(i)
}
wg.Wait()
fmt.Println("Main: Waiting for workers to finish")
fmt.Println("Main: Completed")
}
- 2 回答
- 0 關注
- 115 瀏覽
添加回答
舉報