在提供的程式碼中,目的是讓主goroutine 透過使用通道和通道來列印從1 到11 的數字。等組。但是,它偶爾會跳過數字 11,導致輸出不完整。
問題是由於將sync.WaitGroup 錯誤地傳遞給外部函數Print 所引起的。透過將 WaitGroup 的副本傳遞給函數,它無法對主 goroutine 正在等待的原始等待群組執行必要的 Done() 呼叫。
最佳解決方案:
建議的解決方案包括修改代碼如下:
<code class="go">func main() { ch := make(chan int) var wg sync.WaitGroup wg.Add(2) go Print(ch, &wg) go func() { for i := 1; i <= 11; i++ { ch <- i } close(ch) defer wg.Done() }() wg.Wait() } func Print(ch <-chan int, wg *sync.WaitGroup) { for n := range ch { // reads from channel until it's closed fmt.Println(n) } defer wg.Done() }</code>
在此修復中,Print函數接收指向等待群組的指針,確保在
替代解決方案:
或者,可以透過直接關閉通道來消除Print 函數中對WaitGroup 的需求發送完所有數字後:
<code class="go">func Print(ch <-chan int) { for n := range ch { // reads from channel until it's closed fmt.Println(n) } }</code>
在這種情況下,主Goroutine必須等待通道關閉:
<code class="go">wg.Wait() close(ch)</code>
以上是為什麼在外部函數中使用 Sync.WaitGroup 的副本會導致 goroutine 中輸出遺失?的詳細內容。更多資訊請關注PHP中文網其他相關文章!