這是我的意思的一個(gè)簡(jiǎn)單例子package mainimport ( "sync" "testing" "time")func TestWaitGroup(t *testing.T) { var wg sync.WaitGroup quitSig := make(chan struct{}) go func(wg sync.WaitGroup, quitChan, chan struct{}) { defer func() { t.Log("Done...") wg.Done() t.Log("Done!") }() t.Log("waiting for quit channel signal...") <-quitChan t.Log("signal received") }(wg, quitSig) time.Sleep(5*time.Second) t.Log("Done sleeping") close(quitSig) t.Log("closed quit signal channel") wg.Wait() t.Log("goroutine shutdown")}當(dāng)我運(yùn)行它時(shí),我得到以下信息=== RUN TestWaitGroup main.go:18: waiting for quit channel signal... main.go:23: Done sleeping main.go:25: closed quit signal channel main.go:20: signal received main.go:14: Done... main.go:16: Done! 它只是掛起直到超時(shí)。如果你只是做defer wg.Done()同樣的行為觀察。我在跑go1.18。這是一個(gè)錯(cuò)誤還是我在這種情況下沒(méi)有正確使用 WaitGroups?
2 回答

月關(guān)寶盒
TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超5個(gè)贊
兩個(gè)問(wèn)題:
不要復(fù)制
sync.WaitGroup
:來(lái)自文檔:A WaitGroup must not be copied after first use.
在開(kāi)始你的工作之前你需要一個(gè)
wg.Add(1)
- 與wg.Done()
wg.Add(1) // <- add this
go func (wg *sync.WaitGroup ...) { // <- pointer
}(&wg, quitSig) // <- pointer to avoid WaitGroup copy
https://go.dev/play/p/UmeI3TdGvhg

翻閱古今
TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超5個(gè)贊
您正在傳遞等待組的副本,因此 goroutine 不會(huì)影響在外部范圍內(nèi)聲明的等待組。通過(guò)以下方式修復(fù)它:
go func(wg *sync.WaitGroup, quitChan, chan struct{}) {
...
}(&wg, quitSig)
- 2 回答
- 0 關(guān)注
- 160 瀏覽
添加回答
舉報(bào)
0/150
提交
取消