ゴルーチンのバッファなしチャネルのデッドロック
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() /home/tarrsalah/src/go/src/github.com/tarrsalah/tour.golang.org/65.go:8 +0x52 exit status 2
このデッドロックが発生する理由を理解するには、まずバッファリングされていないチャネルの動作を理解する必要があります。
バッファリングされていないチャネルの詳細
Go の公式ドキュメントに記載されているように、「チャネルがバッファされていない場合、送信者は受信者が値を受信するまでブロックします。チャネルにバッファがある場合、送信者はバッファがいっぱいの場合、値がバッファにコピーされるまでブロックします。これは、受信者が値を取得するまで待機することを意味します。値。"
簡単に言うと、
デッドロック シナリオ
提供されたコード スニペットでは、チャネルがバッファリングされておらず、他にバッファリングされていないため、操作 c
デッドロックの解除
デッドロックを解決するには、次のいずれかを行うことができます。
OR
受信ゴルーチンの例:
package main import "fmt" func main() { c := make(chan int) go func() { fmt.Println("received:", <-c) }() c <- 1 }
ここでは、 go で作成されたゴルーチンを示します。 func() {...} はチャネルからの値の受信を継続的に待ちます。この受信ゴルーチンを導入することで、デッドロックが防止されます。
結論として、専用の受信メカニズムを持たずに同じゴルーチン内でバッファリングされていないチャネルを使用すると、デッドロックが発生する可能性があります。これを回避するには、バッファリングされたチャネルを使用するか、別個の受信ゴルーチンを導入して、同時ゴルーチン間で適切なデータ転送を確保することを検討してください。
以上がGo のバッファリングされていないチャネルがデッドロックを引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。