使用 Goroutine 進行資料處理
在 Go 中,goroutine 是一種輕量級線程,可以實現任務的並發執行。使用 goroutine 時,在處理後正確收集結果以避免死鎖非常重要。
問題陳述
考慮以下程式碼片段:
sampleChan := make(chan sample) var wg sync.WaitGroup // Read from contents list for i, line := range contents { wg.Add(1) // Process each item with a goroutine and send output to sampleChan go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg) } wg.Wait() // Read from sampleChan and put into a slice var sampleList []sample for s := range sampleChan { sampleList = append(sampleList, s) } close(sampleChan)
此程式碼嘗試使用goroutine 處理清單中的項目並將結果收集到切片中。然而,它遇到了死鎖錯誤,因為在收集結果之前通道已關閉。
解決方案
要解決這個問題,我們可以非同步關閉通道工人們已經完成加工。以下是修正後的程式碼:
for i, line := range contents { wg.Add(1) // Process each item with a goroutine and send output to sampleChan go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg) } go func() { wg.Wait() close(sampleChan) }() for s := range sampleChan { .. }
此程式碼啟動處理項目並將結果傳送到sampleChan 的goroutines。同時,它還啟動另一個 goroutine,等待所有工作執行緒完成,然後關閉通道。這可以確保在通道關閉之前收集所有結果。
替代解決方案
為了更好的程式碼可讀性和可測試性,建議使用同步 newSample 函數和句柄主 Goroutine 中的並發性。
for i, line := range contents { wg.Add(1) go func(line string) { defer wg.Done() sampleChan <- newSample(line, *replicatePtr, *timePtr) }(line) }
這種方法使並發原語保持在地化,簡化程式碼維護並降低錯誤風險。
以上是從 Goroutine 收集結果時如何避免死鎖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!