使用WaitGroup等待緩衝通道為空
在並發程式設計中,通常需要控制並發執行的goroutines的數量。一種常見的方法是使用緩衝通道作為信號量。但是,請務必注意此方法的局限性。
考慮以下範例:
ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} sem := make(chan struct{}, 2) for _, i := range ints { sem<- struct{}{} go func(id int, sem chan struct{}) { // do something <-sem }(i, sem) }
此程式碼使用大小為 2 的緩衝通道 (sem) 來限制並發數量goroutine 變成 2。但是,有一個問題:程式可能會在最後幾個 goroutine 完成其任務之前結束。這是因為緩衝通道在處理過程中的任何時候都可能變空,即使程式正在調度更多的 goroutine。
要等待緩衝通道耗盡,我們不能依賴通道本身。相反,我們可以使用sync.WaitGroup來追蹤未完成的goroutines的數量:
sem := make(chan struct{}, 2) var wg sync.WaitGroup for _, i := range ints { wg.Add(1) sem<- struct{}{} go func(id int) { defer wg.Done() // do something <-sem }(i) } wg.Wait()
在這個修改後的程式碼中,我們在分派每個goroutine之前使用wg.Add(1)來增加等待組。當 goroutine 完成其任務時,defer wg.Done() 語句會遞減等待群組。最後,wg.Wait() 會阻塞,直到等待群組達到零,以確保所有 goroutine 都已完成執行。這種方法允許我們等待通道耗盡並確保程式不會過早終止。
以上是使用緩衝通道作為信號量時如何確保所有 Goroutine 完成?的詳細內容。更多資訊請關注PHP中文網其他相關文章!