Go の同時実行モデルのデッドロック: バッファなしチャネルの使用
Go 同時実行モデルでは、チャネルはゴルーチン間の通信の基本的なメカニズムです。ただし、チャネルの動作はバッファ サイズに応じて異なる場合があります。ここでは、バッファなしチャネルを使用するときに発生するデッドロック シナリオについて詳しく説明します。
問題
次の Go コード スニペットを考えてみましょう。
package main import "fmt" func main() { c := make(chan int) c <- 1 fmt.Println(<-c) }
このコードを実行すると、デッドロック:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send]: main.main() /path/to/file:8 +0x52 exit status 2
説明
デッドロックは、バッファリングされていないチャネルの使用が原因で発生します。ドキュメントに記載されているように、バッファなしチャネルでは、値を送信する前に受信者の存在が必要です。この場合、チャネルはデフォルトでバッファなし (バッファ サイズ 0) として初期化されます。
行 c
同時に、fmt.Println(<-c) ステートメントはチャネルから値を受信しようとします。ただし、まだ値が送信されていないため (ゴルーチンが受信者を待っているため)、受信操作はブロックされます。
両方のゴルーチンが他方のゴルーチンが操作を完了するのを待っているため、デッドロックが発生します。
解決策
デッドロックを解決するには、チャンネルの受信機。送信された値の受信を処理する別のゴルーチンを作成することで、デッドロックを解消できます。以下の変更されたコードは、この解決策を示しています:
package main import "fmt" func main() { c := make(chan int) go func() { fmt.Println("received:", <-c) }() c <- 1 }
以上がGo でバッファなしチャネルを使用するとデッドロックが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。