首頁 >後端開發 >Golang >為什麼在同一個 Goroutine 中的無緩衝通道上發送和接收會導致 Go 死鎖?

為什麼在同一個 Goroutine 中的無緩衝通道上發送和接收會導致 Go 死鎖?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-23 01:20:15965瀏覽

Why Does Sending and Receiving on an Unbuffered Channel in the Same Goroutine Cause a Deadlock in Go?

理解Go 並發中的死鎖:Goroutine 中的無緩衝通道

在Go 的並發模型中,通道是Goroutine 之間通信的重要工具。但是,通道使用不當可能會導致死鎖,如以下程式碼片段所示:

執行時,此程式碼會導致死鎖,並顯示以下錯誤訊息:

為什麼會發生這種死鎖?

問題在於使用了無緩衝通道相同的協程。無緩衝通道沒有內部存儲,這表示向無緩衝通道發送值會阻塞,直到另一個 goroutine 讀取該值。

在這種情況下,goroutine 會向通道 c 發送一個值,並嘗試從同一頻道依序進行。由於沒有其他 goroutine 接收該值,因此發送方 goroutine 無限期掛起,導致死鎖。

如何修復它?

有兩種解決方案:

  1. 建立緩衝通道:透過建立具有緩衝區的通道,允許在阻塞發送者goroutine 之前儲存多個值。例如:

這將建立一個緩衝區大小為 1 的通道,允許在不阻塞的情況下儲存一個值。

  1. 使用單獨的通道用於發送的 goroutine: 不要在同一個 goroutine 中發送,而是創建一個單獨的 goroutine 來將值發送到通道。例如:

在這個範例中,sender goroutine 非同步向通道 c 發送一個值。然後主 Goroutine 從通道接收值,而不會遇到死鎖。

了解無緩衝通道的行為並避免不當使用對於編寫高效且非阻塞的並發 Go 程式至關重要。

以上是為什麼在同一個 Goroutine 中的無緩衝通道上發送和接收會導致 Go 死鎖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn