2 回答
TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超3個(gè)贊
文檔指出,“如果重用 a 來等待多組獨(dú)立的事件,則必須在所有以前的 Wait 調(diào)用返回后進(jìn)行新的 Add 調(diào)用”WaitGroup
在呼叫其他 goroutine 之前,您正在呼叫某些 goroutine,這是不允許的,如文檔所述。在你開始所有這些戈魯廷之前,你需要打電話,你還不如叫一次,wg.Done()wg.Add(1)wg.Addwg.Add(1000)
你的其他代碼工作的原因是它從不調(diào)用,你有wg.Done()
if true {
return nil
}
defer wg.Done()
因此,您始終返回而不到達(dá) defer 語句,因此永遠(yuǎn)不會(huì)對(duì) 進(jìn)行任何調(diào)用。wg.Done()
請(qǐng)執(zhí)行下列操作:
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貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊
問題是,如果在等待組上調(diào)用,則不允許重用此等待組并再次調(diào)用它,直到返回調(diào)用(請(qǐng)參閱文檔)。在此程序中,調(diào)用工作函數(shù)本身就是一個(gè) go 例程,所有調(diào)用工作函數(shù)都同時(shí)運(yùn)行。在沒有等待對(duì)方的情況下,他們?cè)噲D在上一個(gè)電話未完成時(shí)打電話。Wait()Add()Wait()Add()Wait()
第一個(gè)工作線程生成結(jié)果時(shí)沒有錯(cuò)誤,因?yàn)樗麄兊恼{(diào)用在下一個(gè)調(diào)用(一個(gè)經(jīng)典的競(jìng)爭(zhēng)條件)之前幸運(yùn)地返回。Wait()Add()
如果您希望工作線程同時(shí)運(yùn)行,則必須移動(dòng)并退出調(diào)用工作器函數(shù)。 必須在 for 循環(huán)之后調(diào)用。并且應(yīng)該在調(diào)用工作之前在循環(huán)內(nèi)調(diào)用,否則程序?qū)⒃赾allWorker有機(jī)會(huì)向等待組添加某些內(nèi)容之前完成,因此無需等待。不需要時(shí)間。睡在里面,太。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 關(guān)注
- 142 瀏覽
添加回答
舉報(bào)
