Goroutines 是 Go 中並發程式設計的基本概念。它們允許您同時執行多個任務,而不會阻塞主執行緒。然而,使用 goroutine 可能會很棘手,尤其是在從多個 goroutine 收集結果時。
問題陳述
一位開發人員嘗試使用 goroutine 來處理一系列items 並將處理後的值收集到切片中。然而,他們遇到了可怕的“所有 goroutine 都在睡覺——死鎖!”錯誤。
死鎖的根本原因
發生死鎖是因為程式碼在嘗試收集結果之前等待所有 goroutine 完成處理。這就造成了這樣一種情況:goroutine 正在等待切片可供寫入,而主線程正在等待 goroutine 完成處理。
解決方案
為了解決死鎖,需要引入非同步關閉用於goroutine和主執行緒之間通訊的通道。下面修改後的程式碼顯示了解決方案:
// ... // Create a channel to receive the processed values sampleChan := make(chan sample) var wg sync.WaitGroup // Process each item in the list with a goroutine for i, line := range contents { wg.Add(1) go func(line string) { defer wg.Done() // Process the item and send the result on the channel sampleChan <- newSample(line, *replicatePtr, *timePtr) }(line) } // Asyncronously close the channel when all goroutines are done go func() { wg.Wait() close(sampleChan) }() // Read from the channel and gather results into a slice var sampleList []sample for s := range sampleChan { sampleList = append(sampleList, s) } // ...
透過非同步關閉通道,即使 goroutine 仍在處理,主執行緒也可以繼續收集結果。這打破了死鎖,讓程式碼能夠正確執行。
其他注意事項
值得注意的是,雖然這個解決方案解決了死鎖,但它並不是一個完整的解決方案用於管理此特定場景中的並發性。根據需求和 goroutine 的數量,可能需要額外的同步和錯誤處理機制來確保程式碼的可靠性和正確性。
以上是從 Go 中的 Goroutine 收集結果時如何避免死鎖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!