第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

wg.Add() 放在哪里

wg.Add() 放在哪里

Go
慕絲7291255 2022-07-18 16:54:15
var wg sync.WaitGroupvar v int32 = 0 for i = 0; i < 100; i++{   go func(){       wg.Add(1) // wrong place       atomic.AddInt32(&v,1)       wg.Done()   } }wg.Wait()fmt.Println(v)這是我從該視頻中看到的一段代碼https://subscription.packtpub.com/video/application_development/9781788994880/97598/97608/goroutines但是v總是小于100,我認(rèn)為原因可能是wg.Wait()比預(yù)期更早結(jié)束,因?yàn)槲覀儼褀g.Add(1)匿名函數(shù)放在里面,并且在同一個(gè) goroutinewg.Done()中會(huì)立即被調(diào)用,因此 main goroutine 從阻塞狀態(tài)恢復(fù)執(zhí)行。但是如果我們將wg.Add(1)放入 for 循環(huán)中, v 將永遠(yuǎn)是100。var wg sync.WaitGroupvar v int32 = 0 for i = 0; i < 100; i++{   wg.Add(1)   go func(){       atomic.AddInt32(&v,1)       wg.Done()   } }wg.Wait()fmt.Println(v)我的問題是為什么我們可以保證 main goroutine 總是會(huì)在這里阻塞,使得 v 最終等于 100。如果在 for 循環(huán)之前添加一個(gè)任務(wù)到wg, 并且 main goroutine 在這里恢復(fù)執(zhí)行,那是否可能,因?yàn)榇藭r(shí)沒有任務(wù)。
查看完整描述

2 回答

?
慕田峪7331174

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超13個(gè)贊

wg.Add()在啟動(dòng)將調(diào)用的 goroutine 之前,您應(yīng)該始終調(diào)用wg.Done().

在您更正的示例中,maingoroutine 只能wg.Wait()for循環(huán)之后到達(dá),這可以保證您調(diào)用wg.Add()一百次,因此wg.Wait()會(huì)阻塞直到wg.Done()被調(diào)用100次數(shù)。

當(dāng)wg.Add()調(diào)用在新的 goroutine 中時(shí),不能保證任何wg.Add()調(diào)用都會(huì)在maingoroutine 到達(dá)之前執(zhí)行,wg.Wait()因?yàn)樗鼈兪遣l(fā)運(yùn)行的(在此之前沒有同步)。這種情況下的行為是不確定的(取決于 goroutine 調(diào)度程序,它在沒有顯式同步的情況下是不確定的)。

請(qǐng)注意,如果您知道循環(huán)100進(jìn)行迭代,另一種選擇是wg.Add(100)在循環(huán)之前調(diào)用。我建議不要這樣做,因?yàn)楫?dāng)循環(huán)包含breakcontinue操作時(shí),這需要小心,這可能會(huì)導(dǎo)致啟動(dòng)的 goroutine 更少,從而最終你的maingoroutine 會(huì)卡住。是的,在您的情況下,這可能是微不足道的,但如果此代碼及時(shí)發(fā)展,它可能會(huì)變得不那么明顯,并可能導(dǎo)致未來的錯(cuò)誤。當(dāng)場(chǎng)景中涉及啟動(dòng) goroutine 時(shí),說它更快是無(wú)關(guān)緊要的。如果您只wg.Add(1)在啟動(dòng) goroutine 之前調(diào)用,那么稍后您是否有條件地跳過這部分也沒關(guān)系,因?yàn)槟鷮⒃?code>wg.Add()啟動(dòng) goroutine 的同時(shí)跳過,并且您的代碼將保持正確。

使用時(shí)要遵循的簡(jiǎn)單“規(guī)則” sync.WaitGroup:(引自this answer

  • 在語(yǔ)句之前調(diào)用WaitGroup.Add()“原始”goroutine(開始一個(gè)新的)go

  • 建議調(diào)用WaitGroup.Done()deferred,所以即使 goroutine 發(fā)生恐慌它也會(huì)被調(diào)用

  • 如果你想傳遞WaitGroup給其他函數(shù)(而不是使用包級(jí)變量),你必須傳遞一個(gè)指向它的指針,否則WaitGroup(這是一個(gè)結(jié)構(gòu))將被復(fù)制,并且Done()不會(huì)觀察到在復(fù)制上調(diào)用的方法在原版上


查看完整回答
反對(duì) 回復(fù) 2022-07-18
?
吃雞游戲

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個(gè)贊

就像其他人提到的那樣wg.add(),應(yīng)該在調(diào)用任何 go 例程之前調(diào)用。所以在主線程里面:


一開始就推遲是一種很好的做法,這樣你就不會(huì)忘記,因?yàn)樗灰暈榍謇硇袆?dòng)。


var wg sync.WaitGroup

var v int32 = 0 

for i = 0; i < 100; i++{

   wg.Add(1) //right place to put wg.add(1)

   go func(){

       defer wg.Done()

       atomic.AddInt32(&v,1)

   } 

}

wg.Wait()

fmt.Println(v)


查看完整回答
反對(duì) 回復(fù) 2022-07-18
  • 2 回答
  • 0 關(guān)注
  • 545 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)