Go 中的死鎖:WaitGroup 和緩衝通道
在Go 中,當並發goroutine 無限期地等待彼此完成時,就會發生死鎖。死鎖的一個常見原因涉及使用 WaitGroups 和緩衝通道。
死鎖範例
考慮以下程式碼:
<code class="go">package main import "fmt" import "sync" func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() ch <- m // Sending to a full channel return }() } wg.Wait() for c := range ch { fmt.Printf("c is %v", c) } }</code>
此程式碼打算將5 個空切片傳送到容量為4 的緩衝通道,然後在所有goroutine 完成後從通道中讀取。但是,該程式碼會導致死鎖錯誤。
死鎖的原因
死鎖是由於兩個問題引起的:
解決方案
要解決死鎖,請進行以下修改之一:
解決方案1:
將通道容量增加到5(或更多)並在發送完所有資料後將其關閉:
<code class="go">ch := make(chan []int, 5) ... wg.Wait() close(ch)</code>
解決方案2:
啟動一個單獨的goroutine從通道讀取數據,並在接收到所有數據後通知主goroutine:
<code class="go">func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { ch <- m wg.Done() }() } go func() { for c := range ch { fmt.Printf("c is %v\n", c) wg.Done() } }() wg.Wait() }</code>
以上是在 Go 中使用 WaitGroups 和緩衝通道時如何防止死鎖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!