解決Go 並發中的Goroutine 死鎖
在並發Go 程式中,當Goroutine 無限期地等待對方釋放資源時,可能會出現死鎖。要解決此類死鎖,請考慮以下範例:
<code class="go">// Create a channel for communication between goroutines. ch := make(chan int) // Start producer goroutines that send values to the channel. go producer(ch, 100*time.Millisecond, 2) go producer(ch, 200*time.Millisecond, 5) // Indefinite loop to continuously receive values from the channel. for { fmt.Println(<-ch) }</code>
此程式碼會導致死鎖錯誤:「致命錯誤:所有goroutine 都在睡眠- 死鎖!」發生這種情況是因為生產者的生命週期有限,最終會停止傳輸,而消費者goroutine 則無休止地等待新值。為了避免這種僵局,可以採取兩種主要策略:
1。通道終止:
由於通道只能關閉一次,因此生產者向消費者發出終止訊號至關重要。協調員可以監控生產者的完成情況並相應地關閉通道。
2.協調同步:
使用像sync.WaitGroup這樣的同步原語,生產者可以在完成時通知協調者,協調者可以在所有生產者完成後關閉通道。
使用同步更新程式碼:
<code class="go">import ( "fmt" "sync" "time" ) func producer(ch chan int, d time.Duration, num int, wg *sync.WaitGroup) { defer wg.Done() for i := 0; i < num; i++ { ch <- i time.Sleep(d) } } func main() { // Create a WaitGroup for coordinating producer completion. wg := &sync.WaitGroup{} // Initialize the channel for communication between goroutines. ch := make(chan int) // Start producer goroutines. wg.Add(2) go producer(ch, 100*time.Millisecond, 2, wg) go producer(ch, 200*time.Millisecond, 5, wg) // Assign a goroutine to close the channel when all producers have finished. go func() { wg.Wait() close(ch) }() // Iterate over values from the channel until it's closed. for v := range ch { fmt.Println(v) } }</code>
結論:
透過實現通道終止或同步,開發人員可以有效避免goroutine 死鎖,確保並發Go 程式中的適當協調。
以上是## 如何避免並發Go程式中的死鎖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!