同時実行 Go のデッドロックを理解する: ゴルーチン内のバッファリングされていないチャネル
Go の同時実行モデルでは、チャネルはゴルーチン間の通信に重要なツールです。ただし、次のコード スニペットに示すように、チャネルを不適切に使用するとデッドロックが発生する可能性があります:
package main import "fmt" func main() { c := make(chan int) c <- 1 fmt.Println(<-c) }
このコードを実行すると、次のエラー メッセージが表示されてデッドロックが発生します:
fatal error: all goroutines are asleep - deadlock!
このデッドロックはなぜ発生しますか?
問題は、バッファリングされていないメソッドの使用にあります。同じゴルーチン内のチャネル。バッファーなしチャネルには内部ストレージがありません。つまり、バッファーなしチャネルへの値の送信は、別のゴルーチンが値を読み取るまでブロックされます。
この場合、ゴルーチンはチャネル c に値を送信し、チャネル c から値を受信しようとします。同じチャンネルを連続して再生します。値を受け取る他の goroutine がないため、送信側の goroutine が無期限にハングし、デッドロックが発生します。
どうすれば修正できますか?
解決策は 2 つあります。 :
c := make(chan int, 1)
これにより、バッファ サイズ 1 のチャネルが作成され、ブロックせずに 1 つの値を格納できるようになります。
package main import "fmt" func main() { c := make(chan int) go func() { c <- 1 }() fmt.Println(<-c) }
この例では、送信側ゴルーチンはチャネル c に値を非同期で送信します。その後、メインの goroutine は、デッドロックが発生することなくチャネルから値を受け取ります。
バッファリングされていないチャネルの動作を理解し、不適切な使用を回避することは、効率的でノンブロッキングの同時実行 Go プログラムを作成するために重要です。
以上が同じゴルーチン内のバッファリングされていないチャネルで送受信すると Go でデッドロックが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。